TIL: x &= (x - 1) deletes the rightmost 1 bit in x
published
last modified
2kb
Why does this happen? The a-ha moment is to see what happens when we add to which equals . Say we have the number in decimal as our , and add one to it, this would look like:
1010 +
0001
The result would be (11 = x):
1011
The astute observer would notice that in there is a zero at the first one bit in . This is because, what adding to will do is place a bit into the first open position (the first 0). This means that first zero in will correspond to the first 1 bit in . So if we bitwise & this with the original number this will drop that bit (the rightmost 1 bit) in .
1010 &
1011
----
1010
Why Does This Even Matter?
Well, with this interesting fact counting bits in an integer becomes slighly faster than just right shifting the integer and checking if the bitwise & of 1 and x is equal to 1. The primitive countbits
may look like this:
int o_countbits(unsigned x) {
int count = 0;
for (; x != 0; x >>= 1) {
if ((x & 1) == 1) {
++count;
}
}
return count;
}
Which will have to right shift for every position in x. But with our new found knowledge we can re-write this as:
int n_countbits(unsigned x) {
int count = 0;
// deletes the right most 1 bit every iteration
for (; x != 0; x &= (x - 1)) {
++count;
}
return count;
}
This way we don't have to count any of the zeroes in the integer. Awesome! +1 for micro optimisations.
Contact
If you have any comments or thoughts you can reach me at any of the places below.