messing with bits and 8bit variables

Hello everyone!

I tried to mess with the bit operators, yet couldn't figure this one out.

I have char a and its bits [11000011] and char b [10101010].
What i want to do is add those a and b bits together, a starting from bit 2 from left, so it would look like this:

[11000011] // a
[10101010] // b
[11101010] // result


its like having a array for example char a[8] and char b[8] and you do this:
a[1] = b[0]
a[2] = b[1]
and so on ...

one another crazy thing what i want to do is
add a and b bits together, b starting from 2 and ending in 5, example:
[10101010] // a
[01011000] // b
[11011010] // result

my wish would be handle bits like arrays but without having to set each
bit manually like this &= ~(1<<0) or this |= (1<<0)

The purpose would be manipulate bits as fast as possible.
There's one another crazy one coming but lets see first whether this is
possible or not.

Thanks!

my wish would be handle bits like arrays
http://en.cppreference.com/w/cpp/utility/bitset
Last edited on
In regards to your addition, the result should be:

[10101010] // a
[01011000] // b
1[00000010] // result (with overflow)
@MiiniPaa
Well, this is my fault because of the lack of explanation.
Im sorry about that but anyways.

First, am i right that
std::bitset<8> a;
a[0] = 1 <-- that will cost the speed of function?
because operator [] is the function not like in example
int u[8]
u[1] = 1 <<-- this.

I'm writing new compression thingy.

code:http://pastebin.com/xHCSjti1
The code doesn't work tho.
Need to recode everything because im terrible.

The idea is to make normal data what is 1D to 2D like this:
123412341234123412341234
to this:
1234
1234
1234
1234
1234
1234

then check the elements from up to down.
let the x be width and let the y be height.

This is how i would check the numbers:
1
2
3
4
5
6
7
8
9
int x, y;
char data[24]; // inside of this are numbers: 12341234...
for( x = 0; x < 4; x++ )
{
    for( y = 0; y < 6; y++ )
    {
         if( data[x+(y*4)] )
    }
}


But instead of checking numbers, i check bits.
I'm not sure how nice my data compressor will be but
watching how bits nest in files, my idea could not turn out to be
a waste of time.

Btw this is how i check bits right now:
 
if( data[(x/8)+(y*4)] & (1 << x % 8) )


I think that there might be a better way to do this.
Faster way...

I have been thinking about the ways for 2 days now and
the best solution is the one i have right now.

Sure i could check all 8bits with few operator call like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
char prevchanges;
char changes;
char a;
char b;
changes = a ^ b 
if(changes != prevchanges) // something has change


// this is what it should do:
// 01110010 ^ 
// 10101010 
// ------------
// 11011000 


The problems with that would be that it would be rather too
complicated to write a logic code what decompressor can understand.
Also taking this a count that the goal is to use smallest possible data amount to mark down the ways what decompressor would understand and know how to decompress the whole data.







a[0] = 1 <-- that will cost the speed of function?
It would cost something, as extracting a single bit from machine word is not free. Although it will be at least as effective as code written by you: this class was written by experts who knows how computer works and how to write effective code.
operator[] is an inline function in this case
Okay, lets test that:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
LARGE_INTEGERt_start_counter, t_current_counter;
void tstart()
{
	QueryPerformanceCounter(&t_start_counter);
}

double tend()
{
	QueryPerformanceCounter(&t_current_counter);
	double out;
	out = (double)(t_current_counter.QuadPart - t_start_counter.QuadPart);
	out *= 0.000001;
	return out;
}

void main()
{
	double t1 = 0.0, t2 = 0.0;
	int a;
	bitset<8> b1;
	b1[0] = 0;
	char b2 = 0;

	tstart();
	for( a = 0; a < 1000000; a++ )
	{
		if(b1[0]) break;
	}
	t1 = tend();

	tstart();
	for( a = 0; a < 1000000; a++ )
	{
		if(b2 & (1<<0)) break;
	}
	t2 = tend();
	cout << "times:" << t1 << "/" << t2 << " ration:" << t1 / t2 << endl;
}


results:
times:0.344233/0.006841 ration:50.3191

Tested on windows and compiled with microsoft visual c++ 2010
I noticed that my compiler treats inline functions as normal one.
By that i meant that there's no speed differences using inline or normal.

I'm not sure why or should it be that way.
It would be amazing tho if inline would be faster.
Last edited on
Are you compiling in debug or release mode? In debug mode Studio adds code for access/leak control so perfomance will be worse.
Do you have optimisation turned on? Boilerplate code will be eliminated and inline function be substituted if optimisations are turned on.
Here is what I get:
times:0/1e-006 ration:0

Yes, i was compiling in debug mode.
Now i changed it to release and this is what i did with my c++ optimization:
http://oi61.tinypic.com/2r2srhs.jpg

i tried in c++ optimization pretty much every option yet the results
of mine are still same.


Also just in case writing here the full source code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>

#include <windows.h>
#include <math.h>
#include <tchar.h>
#include <sys/stat.h>
#include <time.h>
#include "lzma.h"
#include <bitset>
using namespace std;

LARGE_INTEGER t_start_counter, t_current_counter;
void tstart()
{
	QueryPerformanceCounter(&t_start_counter);
}

double tend()
{
	QueryPerformanceCounter(&t_current_counter);
	double out;
	out = (double)(t_current_counter.QuadPart - t_start_counter.QuadPart);
	out *= 0.000001;
	return out;
}

int _tmain(int argc, _TCHAR* argv[])
{
	double t1 = 0.0, t2 = 0.0;
	int a;
	bitset<8> b1;
	b1[0] = 0;
	char b2 = 0;

	tstart();
	for( a = 0; a < 1000000; a++ )
	{
		if(b1[0]) break;
	}
	t1 = tend();

	tstart();
	for( a = 0; a < 1000000; a++ )
	{
		if(b2 & (1<<0)) break;
	}
	t2 = tend();
	cout << "times:" << t1 << "/" << t2 << " ration:" << t1 / t2 << endl;

	system("PAUSE");
	return 900; 
}


and here's whole command line from c/c++ - command line:

/Zi /nologo /W0 /WX- /Od /Ob0 /Oy- /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm- /EHsc /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Release\Testapp.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue
/Od
Completely disables optimisation. Remove this key for release builds
/Ob0
Disables inline expansion. Change to /Ob2 for release builds.
/Oy-
Disables yet another optimisation opportunity.
Replace all /O keys with single /Ox or /O2 to get adequate application.
Last edited on
command line now:
/Zi /nologo /W0 /WX- /Ox /Ob2 /Oy /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm- /EHsc /GS- /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Release\Testapp.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue

still same results.
I do not that familiar with Visuall Studio configurations, but you can use alternative compiler and see for yourself
EDIT: Wrong link.
EDIT: Fixed link: http://coliru.stacked-crooked.com/a/1fee8b3f7cc2da46
Had to move around and change code to avoid too smart optimisation. Sadly resolution of clock is too coarse to really measure something, but at least it shows that speed is comparable.
EDIT: replaced link again. Silly mistake. Now those result are completely similar.
Last edited on
Thanks for everything!

Its working now.
The problem was that if i changed the compile type to release then
the folder where .exe went also changed.
I didn't noticed that somewhy.

At least now i don't have to use those #defines and make
my code extremely complicated.
Topic archived. No new replies allowed.