I\'m preparing for an interview using the text, \"Cracking the Coding Interview\" by Gayle Laakman McDowell. On the section covering bit manipulation, there are two function
For the first question:
lets say i = 5
(1 << i ) = 0010 0000 = 32 in base 10
(1 << i ) -1 = 0001 1111 = 31
So a &
with this mask clears the most significant bit down to i because all bit positions above and including index i
will be 0 and any bellow will be 1.
For the second question:
Again lets say i = 5
(1 << (i + 1)) = 0100 0000 = 64 in base 10
(1 << (i + 1)) - 1 = 0011 1111 = 63
~((1 << (i + 1)) - 1) = 1100 0000 = 192
So a &
with this masks clears bits up to index i
let's assume i= 5
(1 << i)
give you 0100000
the 1 is placed in the 6th bit position
so now if we substract 1
from it, then we get 0011111
==> only the 5 first bit are set to 1
and others are set to 0
and that's how we get our mask
Conclusion: for a giving i
the (1 << i) -1
will give you a mask with the i
first bits set to 1
and others set to 0
First Function:
Let's take i=3
for example. (1 << i)
would yield 1000
in binary. Subtracting 1 from that gives you 0111
in binary (which is i number of 1's). ANDing that with the number will clear all but the last i bits, just like the function description says.
Second Function:
For the second function, the same applies. If i=3
, then ((i << (i+1)) - 1)
gives us 01111
. The tilde inverts the bits, so we have 10000
. It's important to do it this way instead of just shifting i
bits left, because there could be any number of significant bits before our mask (so 10000
could be 8 bits long, and look like 11110000
. That's what the tilde gets us, just to be clear). Then, the number is ANDed with the mask for the final result
// To clear all bits from the most significant bit through i (inclusive), we do:
int clearMSBthroughI(int num, int i) {
int mask = (1 << i) - 1;
return num & mask;
}
Take the example of i = 3
1<<3 gives you 0x00001000
(1<<3)-1 gives you 0x00000111
num & (1<<i)-1 will clear the bits from msb to i
// To clear all bits from i through 0 (inclusive), we do:
int clearBitsIthrough0(int num, int i) {
int mask = ~(((1 << (i+1)) - 1);
return num & mask;
}
same example of i = 3 gives you
1 <<(3+1) =0x00010000
1 <<(3+1)-1 = 0x00001111
mask =~(1<<(3+1)-1) = 0x11110000
num & mask will cleaR the bits from 0 throuh i