Yes, you simply define an array of your 32-bit integers. Then you manipulate a specific element of the array.
Given a bit ID from 0 through 255 inclusive (for example), that would be an array:
unsigned int bits[8];
In order to find which element to operate on:
unsigned int index = bitId >> 5; // turns 0..255 into 0..31
To get the masks for a given bit ID:
unsigned int masks[] = {
0x0001, 0x0002, 0x0004, 0x0008,
0x0001, 0x0020, 0x0040, 0x0080,
0x0100, 0x0200, 0x0400, 0x0800,
0x1000, 0x2000, 0x4000, 0x8000
};
unsigned int mask = masks[bitId & 0x1f];
If you have the uint32_t
type available in your implementation, that's probably the safest way to go. Otherwise, there are known methods for using unsigned int
using CHAR_BIT
and sizeof
to actually figure out at runtime how big to make the masks
array and what values you should use for discovering the array index and bitmask index.
For example, this snippet from my code library shows how I did it for a character-based bitmask:
static unsigned char bitmask[CHAR_BIT];
void bitsetInit (void) {
unsigned char mask = 1;
int i = 0;
while (i < CHAR_BIT) {
bitmask[i++] = mask;
mask <<= 1;
}
}
and using:
bsp->bits[bitnum/CHAR_BIT] &= ~bitmask[bitnum%CHAR_BIT];
bsp->bits[bitnum/CHAR_BIT] |= bitmask[bitnum%CHAR_BIT];
for clearing and setting bits respectively.
If you wanted to use unsigned int
instead of unsigned char
you would simply calculate the number of bits for that:
unsigned int UINT_BIT = CHAR_BIT * sizeof (unsigned int);
and use it where I've used CHAR_BIT
above (the mask
array can be dynamically allocated at runtime if need be).