Working with a C++ data type on a bit by bit level

Started by
28 comments, last by DanBerliner 13 years ago
I am using C++, I have no decided on a graphics library so I am open to anything that works on Windows and *nix if it makes my life easier. This is more of a theory question though so I don't think it will be relevant which one I am using.

While it is not a game, I am writing a program that allows the user to create a one color overlay over an image with a paintbrush. My first major issue is storing all that data, the program will mainly be used on projectors running at sizes as large as 1920x1080, meaning that it will use a minimum of 1.98mb of data at any given time. My issue is this: there is no one bit data type, the smallest C++ data type is 32 bits. While 1.98mb of data in memory isn't an issue at any level, having 63.4mb of data would be just inefficient. As an electrical engineer I am familiar with binary and know that each int can hold 32 pixels of data, my problem is working with an int in terms of bits.

My question is how would I discern which bits are what? I would need (for instance) the number 2800169371 to correspond to its binary value, 10100110111001110011000110011011, where 1 is on and 0 is off. I would have to go though each bit and see if it on or off.
Advertisement

there is no one bit data type, the smallest C++ data type is 32 bits.
int is 32 bits.
char is 8 bits.
short is 16.

my problem is working with an int in terms of bits.[/quote]
See std::vector<bool>.

It should be specialized to use one bit per value, while working like a regular array.

int is 32 bits.
char is 8 bits.
short is 16.

My mistake there


See std::vector<bool>.

It should be specialized to use one bit per value, while working like a regular array.

I recall reading somewhere that bool was longer than 1 bit, after googling it again I see that I was incorrect. Thanks.

For people who may come here looking for the original requested solution (perhaps for a different issue), the following function will tell you if a bit is on or off in an int data type (you can modify it to use any fundamental data type:

bool isBitOn(int place, int &subject)
{
return ((subject & 1<<place)==0 ? false : true);
}
Its usually easier to use a seperate variable for each component and combining them, than remembering huge numbers for each colour.

unsigned int red = 128;
unsigned int green = 0;
unsigned int blue = 255;
unsigned int alpha = 255;

You can put them all together into an int with some bitwise operators

unsigned int colour = 0;
colour |= (red << 24);
colour |= (green << 16);
colour |= (blue << 8);
colour |= |= alpha;

You can do the opposite to get each individua l component back

red = 0xff000000 & colour; // only want the red bits, so mask the others out
red = red >> 24;

green = 0x00ff0000 & colour;
green = green >> 16;

I'm slightly rusty so it may have mistakes. Your just packing each different component into one int, most significant bytes being red in what I've done. Of course it all depends on what bytes are considered to be what, I've gone for RGBA but you see lots of combination (BRGA etc). No need to deal with individual bits (unless you have to). You can do individual bits in a similar way. Take a look at bitwise operators http://www.cprogramming.com/tutorial/bitwise_operators.html .

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.


Its usually easier to use a seperate variable for each component and combining them, than remembering huge numbers for each colour.

unsigned int red = 128;
unsigned int green = 0;
unsigned int blue = 255;
unsigned int alpha = 255;

You can put them all together into an int with some bitwise operators

unsigned int colour = 0;
colour |= (red << 24);
colour |= (green << 16);
colour |= (blue << 8);
colour |= |= alpha;

You can do the opposite to get each individua l component back

red = 0xff000000 & colour; // only want the red bits, so mask the others out
red = red >> 24;

green = 0x00ff0000 & colour;
green = green >> 16;

I'm slightly rusty so it may have mistakes. Your just packing each different component into one int, most significant bytes being red in what I've done. Of course it all depends on what bytes are considered to be what, I've gone for RGBA but you see lots of combination (BRGA etc). No need to deal with individual bits (unless you have to). You can do individual bits in a similar way. Take a look at bitwise operators http://www.cprogramm..._operators.html .


The program don't allow for more than black and transparent so a 1 bit value per pixel is all that is needed. Thanks for the explanation though.

I recall reading somewhere that bool was longer than 1 bit, after googling it again I see that I was incorrect. Thanks.

bool does indeed take more than one bit. At the very least it takes one byte, and it may take more. However, std::vector<bool> is implemented in some clever way and will store bits compactly, just as you want.

[quote name='Dan Berliner' timestamp='1302120771' post='4795189']
I recall reading somewhere that bool was longer than 1 bit, after googling it again I see that I was incorrect. Thanks.

bool does indeed take more than one bit. At the very least it takes one byte, and it may take more. However, std::vector<bool> is implemented in some clever way and will store bits compactly, just as you want.
[/quote]

Great, so now I cant read. After looking another time I see it is 1 byte, not one bit.

I will go with std::vector<bool>, I currently have a proof of concept written up with simple bools in an array and it is seeing some performance issues on the slow computer running it.
What about the std::bitset data type. I have never used it but I thought this was specifically to work with bits.

So you can do std::bitset <32> myInt;

This is what c++ says about bitset

A bitset is a special container class that is designed to store bits (elements with only two possible values: 0 or 1, true or false, ...).[/quote]
http://www.cplusplus.com/reference/stl/bitset/

What about the std::bitset data type. I have never used it but I thought this was specifically to work with bits.

So you can do std::bitset <32> myInt;

This is what c++ says about bitset

A bitset is a special container class that is designed to store bits (elements with only two possible values: 0 or 1, true or false, ...).

http://www.cplusplus...nce/stl/bitset/
[/quote]

Size is defined at compile time.

bitset is:template < size_t N > struct bitset {
char data[N / 8 + 1];
};



Interestingly enough, this would be something where JIT-based languages could run circles around C++. Unfortunately, Java refuses to add value objects. But it would allow a given instance to generate fully specialized and static code based on run-time parameters.
What about multi dimensional vectors? Would the same advantage apply to a multi dimensional vector? The math gets a little more annoying if it is one dimensional going over a two dimensional screen.

This topic is closed to new replies.

Advertisement