Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Working with bit arrays

Status
Not open for further replies.

Clairvoyant1332

Programmer
May 21, 2003
147
US
There have been a few times when I've found it usefull to define what is essentially a bit array. For example I'll define a variable like
Code:
char flags[100];
and treat it as an array of 800 bits. This is usefull if you want to send a large number of binary flags over a network.

Accessing a single bit in this array does involve a bit of math that might not be immediately obvious to someone reading your code, so here are a few #define's you can use.

Code:
#define ISBITSET(x,i) ((x[i>>3] & (1<<(i&7)))!=0)
#define SETBIT(x,i) x[i>>3]|=(1<<(i&7));
#define CLEARBIT(x,i) x[i>>3]&=(1<<(i&7))^0xFF;

Just like any array, the starting index is 0.

Here,
Code:
x
is your char array and
Code:
i
is your index into the array. So if you want to look at bit index 9 (the 10th bit) in your array, the bit you want is in the second byte (
Code:
x[1]
) two bits over (
Code:
x[1]&1
). In general, you take the index and divide it by 8 (
Code:
x[i/8]
or
Code:
x[i>>3]
) to get the byte you want, then mod the index by 8 (
Code:
(i%8)
or
Code:
(i&7)
)to get the proper bit index within the byte and take 2 to that power (
Code:
(1<<(i&7))
) to create the bitmask to strip out the bit you want (
Code:
x[i>>3] & (1<<(i&7))
).

The set of macros above assume little endian bit ordering within the array. If you've defined your own array, this shouldn't matter. If you're working with someone else's array however, for example when reading a monochrome TIFF file, you may need to use big endian bit ordering. The #define's below use big endian.

Code:
#define ISBITSET(x,i) ((x[i>>3] & (1<<(7-(i&7))))!=0)
#define SETBIT(x,i) x[i>>3]|=(1<<(7-(i&7)));
#define CLEARBIT(x,i) x[i>>3]&=(1<<(7-(i&7)))^0xFF;

Dennis
 
Nice. Why don't you turn this into a FAQ?

 
Yes...I do the same thing.

Alternatively if I don't need as much detail or for smaller 'sets' I use bitfields within a struct.

e.g.

struct OBJECT0_FLAGS
{ BYTE onoff : 1;
BYTE haveres : 1;
BYTE foo : 1;
BYTE bar : 1;
BYTE x : 1;
BYTE y : 1;
BYTE dontcare : 2;
}; *flags;

The nice thing about this is that you can refer to your flag by name (without an enum or some such)
e.g. flags->onoff = TRUE;

Obviously this can be extended to words,dwords etc..

Another useful trick, although perhaps more specialised, is to combine this with an anonymous union to escape the class member in static table problem.

so I might have
struct OBJECT0_FLAGS
{ BYTE onoff : 1;
BYTE haveres : 1;
BYTE foo : 1;
BYTE bar : 1;
BYTE x : 1;
BYTE y : 1;
BYTE dontcare : 2;
};
union (OBJECT0_FLAGS *flags; VOID *vp_flags; }

where the struct belongs to a class FRED.

You can then refer to your struct in static tables for example (using the VOID pointer) and recast for access where necessary within the class. e.g. (BYTE *)this->*flags

Perhaps one step too far but I commonly use tables for this type of thing and, given you can't put pointers to class members in static tables, this provides a neat workaround.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top