Reputation: 53
Hi I am trying to analyze a function
int countBit(uint32_t n) {
n = (n & 0x55555555) + ((n & 0xAAAAAAAA) >> 1);
n = (n & 0xC30C30C3) + ((n & 0x0C30C30C) >> 2) + ((n & 0x30C30C30) >> 4);
return n % 63;
}
Now I've already figured out that it counts the number of set bits (originally the function name has been different so it was not obvious.)
I also know that the line
n = (n & 0x55555555) + ((n & 0xAAAAAAAA) >> 1);
gives the number of 1 in subsequent pairs. However after that I am at lost. Individually I know what the code is doing, but I do not know why it does that and what is the idea behind it.
Upvotes: 1
Views: 133
Reputation: 59323
Oh, I haven't seen this one before. It's pretty clever, although I wonder how fast the modulus is compared to more bit twiddling.
Anyway, after n = (n & 0x55555555) + ((n & 0xAAAAAAAA) >> 1)
, we have 16 2-bit counts.
(n & 0xC30C30C3)
isolates the 6 counts that are shifted by multiples of 6 bits, i.e., multiplied by multiples of 64. Since 64%63 = 1, taking the modulus mod 63 will add all of these together. + ((n & 0x0C30C30C) >> 2)
isolates the counts that are shifted by 6k+2 bits, and adds them to the above. + ((n & 0x30C30C30) >> 4)
does the same for counts that are shifted by 6k+4 bits. After those additions we have 6 5-bit counters that the %63
can add together all at once.
Upvotes: 2