Reputation: 119
I'm forced to use a char array as a bitmap. For instance, this would be a 32-bit bitmap:
char bitmap[4];
Beforehand, I have initialized every single byte of this array to 0. My question is, how can I change a single bit of this array to be the one I want? I'm looking for a function with a similar structure to this, where the bitmap is passed as a parameter, along with the index of the bit we want to change and the value we want to change it to:
set_bit(char *bitmap, int bit, int value);
They force me to use a char array instead of an unsigned char array. It would also be useful to have a get_bit function with a similar structure that only asks for the bitmap and the bit to be probed as arguments.
Thank you in advance.
EDIT: I fixed the type of the bitmap in the set_bit definition
Upvotes: 0
Views: 667
Reputation: 67574
void setbit(void *arr, size_t bit, unsigned val)
{
unsigned char *ucarr = arr; // void * to prevent compiler warnings when you pass other type pointer.
size_t index = bit >> 3; //>>3 is == divide by 8 which is number of bits in char on most systems. Index number
unsigned char mask = 1 << (bit & 7); // &7 - bit number in the 8 bits charackter
ucarr[index] &= ~mask; // zero the bit
ucarr[index] |= mask * (!!val); // set the bit to the value (1 of var nonzero, 0 if var == 0)
}
or if you are sure that val
will be 1
or 0
a bit more efficient version (few clocks)
void setbit1(void *arr, size_t bit, unsigned val)
{
unsigned char *ucarr = arr;
size_t index = bit >> 3;
size_t bitindex = bit & 7;
unsigned char mask = 1 << bitindex;
ucarr[index] &= ~mask;
ucarr[index] |= val << bitindex;
}
or a bit more portable version (CHAR_BIT up to 256)
#define CHO (((CHAR_BIT >> 1) & 1)*2 + ((CHAR_BIT >> 2) & 1)*4 + ((CHAR_BIT >> 3) & 1)*8 + ((CHAR_BIT >> 4) & 1)*16 + ((CHAR_BIT >> 5) & 1)*32 + ((CHAR_BIT >> 6) & 1)*64 + ((CHAR_BIT >> 7) & 1)*128 + ((CHAR_BIT >> 8) & 1)*256)
void setbit(void *arr, size_t bit, unsigned val)
{
unsigned char *ucarr = arr;
size_t index = bit >> CHO;
unsigned char mask = 1 << (bit & (CHAR_BIT - 1));
ucarr[index] &= ~mask;
ucarr[index] |= mask * (!!val);
}
void setbit1(void *arr, size_t bit, unsigned val)
{
unsigned char *ucarr = arr;
size_t index = bit >> CHO;
size_t bitindex = bit & (CHAR_BIT - 1);
unsigned char mask = 1 << bitindex;
ucarr[index] &= ~mask;
ucarr[index] |= val << bitindex;
}
Upvotes: 2