In chapter 2, the section on bitwise operators (section 2.9), I’m having trouble understanding how one of the sample methods works.
Here’s the method provided:
unsigned int getbits(unsigned int x, int p, int n) { return (x >> (p + 1 - n)) & ~(~0 << n); }
The idea is that, for the given number x, it will return the n bits starting at position p, counting from the right (with the farthest right bit being position 0). Given the following main() method:
int main(void) { int x = 0xF994, p = 4, n = 3; int z = getbits(x, p, n); printf('getbits(%u (%x), %d, %d) = %u (%X)\n', x, x, p, n, z, z); return 0; }
The output is:
getbits(63892 (f994), 4, 3) = 5 (5)
I get portions of this, but am having trouble with the ‘big picture,’ mostly because of the bits (no pun intended) that I don’t understand.
The part I’m specifically having issues with is the complements piece: ~(~0 << n). I think I get the first part, dealing with x; it’s this part (and then the mask) that I’m struggling with — and how it all comes together to actually retrieve those bits. (Which I’ve verified it is doing, both with code and checking my results using calc.exe — thank God it has a binary view!)
Any help?
Let’s use 16 bits for our example. In that case,
~0is equal toWhen we left-shift this
nbits (3 in your case), we get:because the
1s at the left are discarded and0s are fed in at the right. Then re-complementing it gives:so it’s just a clever way to get
n1-bits in the least significant part of the number.The "x bit" you describe has shifted the given number (
f994 = 1111 1001 1001 0100) right far enough so that the least significant 3 bits are the ones you want. In this example, the input bits you’re requesting are there, all other input bits are marked.since they’re not important to the final result:As you can see, you now have the relevant bits, in the rightmost bit positions.