这是一小段程序(14行程序),计算数字中设置的位数。
输入输出 - > 0 - > 0(0000000),5 - > 2(0000101),7 - > 3(0000111)
int CountBits (unsigned int x)
{
static unsigned int mask[] = { 0x55555555,
0x33333333,
0x0F0F0F0F,
0x00FF00FF,
0x0000FFFF
} ;
int i ;
int shift ; /* Number of positions to shift to right*/
for (i =0, shift =1; i < 5; i ++, shift *= 2)
x = (x & mask[i ])+ ( ( x >> shift) & mask[i]);
return x;
}
有人可以解释这里使用的算法/为什么会这样做?
答案 0 :(得分:12)
This post更详细地解释了它:
Freed的数字是一个序列的成员,其中第N个数字 序列本身是2 * N 1的从右到左的无限序列 接着是2 * N 0,然后是2 ** N 1,依此类推。最初的 数字是:
...0101010101010101
...0011001100110011
...0000111100001111
...0000000011111111
...
对于16位的字大小,我们有四个“B常数”:
B[1] = 0101010101010101
B[2] = 0011001100110011
B[3] = 0000111100001111
B[4] = 0000000011111111
这就是mask[]
中的那些数字,例如。 0x55555555
是位模式1010101010101010101010101010101
的{{3}}表示。
算法本身就是这样做的:
...依此类推,直到你得到的结果与你需要的多个位一样宽。
我建议您手动使用上面的二进制掩码在纸上试一下。然后,您可能会感觉到该代码所表达的算法。