Hello i m reading chapter in K&R about bit operation whish totally confuses me i understand what all operators does but i dont understand the code itself

unsigned getbits(unsigned x, int p, int n)
{
    return (x >> (p+1-n)) & ~(~0 << n);
}

it will right shift p+1-1 then after that i dont understand

Ever heard of punctuation?

Anyway, I have to admit, that confused me.
This part: ~(~0 << n) will make a binary number containing however many 1's you tell it to, for example...

// ~(~0 << n);

0000001b == ~(~0 << 1)
0000011b == ~(~0 << 2)
0000111b == ~(~0 << 3)
0001111b == ~(~0 << 4)
0011111b == ~(~0 << 5)

I don't really understand what this part does: (x >> (p+1-n) , but maybe somebody else could enlighten both of us.

~(~0 << n) makes a bitmask of ones equal to the number 'n'. does this by first filling the integer full of ones, then shifting them to the left 'n' bits (filling lsb's with zeros), then inverts all the bits.

for instance, n=5 makes a bitmask = '...00000011111' x >> (p+1-n) shifts the original number to the right 'p+1-n' bits.

the whole point is to extract the bits from the original value, starting with the zero-indexed bit # at 'p' (pointer) and extracting 'n' number of bits moving to the right.

the two are ANDed together to get the new, extracted, value

example value = 0x55 (01010101) with p=6 and n=5 will extract bits 6 through bit 2 (total of 5 bits), to find the new value 0x15, (dec 21, or '10101')

01010101
p=6  ^
n=5  .....
     10101   val = 0x15 (d 21)
Comments
Good post.

~(~0 << n) makes a bitmask of ones equal to the number 'n'. does this by first filling the integer full of ones, then shifting them to the left 'n' bits (filling lsb's with zeros), then inverts all the bits.

for instance, n=5 makes a bitmask = '...00000011111' x >> (p+1-n) shifts the original number to the right 'p+1-n' bits.

the whole point is to extract the bits from the original value, starting with the zero-indexed bit # at 'p' (pointer) and extracting 'n' number of bits moving to the right.

the two are ANDed together to get the new, extracted, value

example value = 0x55 (01010101) with p=6 and n=5 will extract bits 6 through bit 2 (total of 5 bits), to find the new value 0x15, (dec 21, or '10101')

01010101
p=6  ^
n=5  .....
     10101   val = 0x15 (d 21)

but srry 1 more question why would it exract to 2 shoudlnt it exract from 6 till the end ?

to clarify, given my example values (val = 0x55, p=6, n=5), look at the first part of the operation: x >> (p+1-n) ... you notice that it will shift 'x' (the value) a total of two places to the right (6+1-5) = 2.

this drops off the first two bits, becasue the formula is asking for the bits #2 through #6 to be extracted. when that shifted value is ANDed with with the bitmask (...0000011111) it pulls out exactly the five bits remaining at the lowest (rightmost) positions once bits #0 and bits #1 were dropped off.


.

This question has already been answered. Start a new discussion instead.