Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange bit twiddling bug

Tags:

c

I have a simple function:

int bitcount( unsigned );

int shiftbit( unsigned val ) {
    return (int)(~0U << (( sizeof(int)*CHAR_BIT ) - bitcount(val)));
}

I'm counting the number of bits in an int and then creating a bitmask which has that number of bits left justified. For example, 0xABCD has 10 bits set and returns the mask 0xFFC0000.

The function works great except when the bitcount is zero in which case I get -1, 0xffffffff when I should just be getting an empty bitmask, i.e. 0x0. It's just not clear to me why it should work for every case except zero.

Answer

So I ended up changing the code as follows, which works fine and should be portable:

int shiftbit( unsigned val ) {
    int bCount = bitcount(val);
    return bCount ? (~0 << (( sizeof(int)*CHAR_BIT ) - bCount)) : 0;
}
like image 564
Robert S. Barnes Avatar asked Jul 27 '26 22:07

Robert S. Barnes


2 Answers

The result of a shift operation is undefined if the number of shifted bits is greater than or equal to the number of bits in the shifted value. So, shifting a 32-bit value by 32 isn't guaranteed to produce anything in particular.

like image 164
Erik Avatar answered Jul 30 '26 12:07

Erik


Because in C the result is undefined if you shift an operand having a size of x bits by x bits. So for example 1 << 32 is undefined (assuming sizeof(int) == 4)

like image 28
ChrisWue Avatar answered Jul 30 '26 11:07

ChrisWue



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!