num &= num - 1;
clears the least significant bit set in num.
This algorithm counts the bits set by clearing them and incrementing a counter until they're all gone.
To understand why it clears the least significant bit, you need to think about what decrementing does to the bits and of course understand what the &
operation does.
Subtracting in binary works just as the process we were all taught in decimal as children.
You work from right (least significant) to left, simply subtracting individual digits when possible, and "borrowing" from the next digit when necessary.
When subtracting 1 from a binary number ending in a set of zeros, this "borrowing" and subtracting turns all the zeros in lower positions than the rightmost 1 to 1's and turns the rightmost 1 to a zero (because it was borrowed).
Then applying the &
operator leaves all the lesser digits zero because they're zero in num
, and sets the least significant bit of num
to zero because it's zero in num-1
.
Both of these operations leave the more significant digits unchanged.
Here's a good list of bit twiddling hacks including this one, which is due to Brian Kernighan.