tadm123 tadm123 - 2 months ago 12
C Question

C rotate bitfield (explanation needed)

I want to rotate a byte 1 bit to the left. I was looking at several examples from this site and came across this code. Though it works, I'd appreciate any step by step into how does it works.

unsigned int _rotl(const unsigned int value, int shift)
{
if ((shift &= sizeof(value)*8 - 1) == 0) //What does this do?
return value;
return (value << shift) | (value >> (sizeof(value)*8 - shift));
}


First of all, what does the first part does? And for the last part wouldn't shifting by that much you'd pretty much be erasing some of the bits?

For example:

Say

value= 0x50 //01010000
shift = 4


I'll have
for

value << shift

01010000 << 4 => 00000000


And for
value >> (sizeof(value)*8 - shift)

01010000>> (4*8 - 4) => 00000000


So doing the OR operation for both would give me 0. My understanding is wrong obviously, but I'd appreciate anyone 'dumbing' it down for a begginer like me. Thanks.

Answer
unsigned int _rotl(const unsigned int value, int shift) 
{
    // If all bits in value are zero, do nothing and return
    int bitmaskOfAllOnes = sizeof(value)*8 - 1;
    if ((shift &= bitmaskOfAllOnes) == 0)           //What does this do?
      return value;

    // Shift value to the left
    (value << shift) 
    // shifting right to handle the wrap around
    | (value >> (sizeof(value)*8 - shift));
}

e.g. using 16-bit ints 
value = 0x1001
shift = 4
sizeof(value) => 2
sizeof(value)*8 - 1 => 0xffff
shift &= bitmaskOfAllOnes => 0x1001 (i.e. not zero)
value << shift => 0x0010
sizeof(value)*8 - shift => 12
value >> (sizeof(value)*8 - shift) => 0x001
0x0010 | 0x001 => 0x0011