If we want to calculate how many bits are set in the number of bits in an integer, our first thought is to loop. Now we can refer to: http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
unsigned int bits_counter_v4(unsigned int x) { // count bits of each 2-bit chunk x = x - ((x >> 1) & 0x55555555); // count bits of each 4-bit chunk x = (x & 0x33333333) + ((x >> 2) & 0x33333333); // count bits of each 8-bit chunk x = x + (x >> 4); // mask out junk x &= 0xF0F0F0F; // add all four 8-bit chunks return (x * 0x01010101) >> 24; }
Thanks to this algorithm, we only need 12 operations to find the number of bits set in int(32). Next, let's analyze this algorithm:
1. The number of "1" obtained by the adjacent 2-bit operation:
Here is the result of the operation we hope to get:
On the left is the digit distribution (4 distributions) ||||| On the right is the number (three results of 0, 1, 2)
00b >> unchanged, still 00b 01b >> unchanged, still 01b 10b >> must be converted to 01b 11b >> must be converted to 10b
Next, the algorithm that can achieve the above effect is given: first shift one bit to the left, give the high-order number to the low-order bit, then 0x55555555 is the mask, set the high-order position to 0, get a new 2-digit number, and then use the original number Subtracting just got the new two-digit number to get our desired result:
00b >> shifted: ?0b >> masked: 00b >> subtraction: 00b - 00b >> 00b 01b >> shifted: ?0b >> masked: 00b >> subtraction: 01b - 00b >> 01b 10b >> shifted: ?1b >> masked: 01b >> subtraction: 10b - 01b >> 01b 11b >> shifted: ?1b >> masked: 01b >> subtraction: 11b - 01b >> 10b
2. The number of "1" obtained by the adjacent 4-bit operation:
In the same way, we put forward expectations:
00b and 00b >> 0000b 00b and 01b >> 0001b 00b and 10b >> 0010b 01b and 00b >> 0001b 01b and 01b >> 0010b 01b and 10b >> 0011b 10b and 00b >> 0010b 10b and 01b >> 0011b 10b and 10b >> 0100b
Algorithm: x = (x & 0x33333333) + ((x >> 2) & 0x33333333 ), here we take 1010b as an example to verify whether the result is 0100b:
1010b ---->>----- 0010b 0011b 0011b ----&---- ----&---- 0010b 0010b -------------+--------------- 0100b
3. The number of "1" obtained by adjacent 8-bit operations:
Algorithm: x = x + (x >> 4); x &= 0x0F0F0F0F;
4. Multiply by 0x01010101
ifA, B, C, D代表8位数,那么32为数可以被(
A, B, C, D
)表示,乘以0x01010101可以使得(
)32>> (A, B, C, D
A+B+C+D, B+C+D, C+D, D
)32
5. We left shift 24 bits to get the sum we want.