c - Setting bits in a bit stream -
i have encountered following c function while working on legacy code , compeletely baffled, way code organized. can see function trying set bits @ given position in bit stream can't head around individual statements , expressions. can please explain why developer used divison 8 (/8) , modulus 8 (%8) expressions here , there. there easy way read these kinds of bit manipulation functions in c?
static void setbits(u8 *input, u16 *bpos, u8 len, u8 val) { u16 pos; if (bpos==0) { pos=0; } else { pos = *bpos; *bpos += len; } input[pos/8] = (input[pos/8]&(0xff-((0xff>>(pos%8))&(0xff<<(pos%8+len>=8?0:8-(pos+len)%8))))) |((((0xff>>(8-len)) & val)<<(8-len))>>(pos%8)); if ((pos/8 == (pos+len)/8)|(!((pos+len)%8))) return; input[(pos+len)/8] = (input[(pos+len)/8] &(0xff-(0xff<<(8-(pos+len)%8)))) |((0xff>>(8-len)) & val)<<(8-(pos+len)%8); }
please explain why developer used divison 8 (/8) , modulus 8 (%8) expressions here , there
first of all, note individual bits of byte numbered 0 7, bit 0 least significant one. there 8 bits in byte, hence "magic number" 8.
generally speaking: if have raw data, consists of n bytes , can therefore treated array of bytes uint8_t data[n]. access bit x in byte array, can example this:
given x = 17, bit x found in byte number 17/8 = 2. note integer division "floors" value, instead of 2.125 2.
the remainder of integer division gives bit position in byte, 17%8 = 1.
so bit number 17 located in byte 2, bit 1. data[2] gives byte.
to mask out bit byte in c, bitwise , operator & used. , in order use that, bit mask needed. such bit masks best obtained shifting value 1 desired amount of bits. bit masks perhaps expressed in hex , possible bit masks byte (1<<0) == 0x01 , (1<<1) == 0x02, (1<<3) == 0x04, (1<<4) == 0x08 , on.
in case (1<<1) == 0x02.
c code:
uint8_t data[n]; ... size_t byte_index = x / 8; size_t bit_index = x % 8; bool is_bit_set; is_bit_set = ( data[byte_index] & (1<<bit_index) ) != 0;
Comments
Post a Comment