我试图了解有关比特的更多信息,但我遇到了this example。
此代码如何计算位数? (顺便说一下,我的C很生锈。)
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; v >>= 1)
{
c += v & 1;
}
答案 0 :(得分:9)
v & 1
中的最低位,则 v
为1,如果不设置则为{0>。
循环继续将每次迭代的v
位右移1位,因此v
的最低位循环遍历原始v
中的每个位(如每一个人在“分数”结束之前都会到达1位置。
因此,它循环遍历每个位,如果设置则将c加1,如果不设置则加0,从而总计原始v中的设置位。
例如,v
的起始1011
:
1011 & 1 = 1
,因此c递增为1。1011
转为101
。101 & 1 = 1
,因此c递增为2。101
转为10
。10 & 1 = 0
,因此c不会增加并保持为2。10
转为1
。1 & 1 = 1
,因此c增加到3。1
转为0
(因为最后一位从小数结束时掉落)。for
循环的条件只是v
,而v现在是0,这是一个假值,循环停止。最终结果,c = 3,正如我们所希望的那样。
答案 1 :(得分:2)
v>> = 1将继续移动最低有效位,直到v全为零。所以我们不要停下来,直到我们把它们都计算在内。 v& 1测试我们即将离开的位是1,所以我们确保在我们将它移开之前计算它。
答案 2 :(得分:1)
v &
基本上提取v
的最低有效位 - 如果设置了该位,则为1
,否则为0
。通过循环的每次迭代,它将v
1个位置向右移动。在每次迭代中,它会将v &
测试的结果添加到计数器c
。所以设置的每一位都意味着1
被添加;每个清除位0
都会被添加。
答案 3 :(得分:1)
基本上,您将1位v
与值1进行比较,并且您知道AND的真值表。
因此,如果来自v
的位为1,则在与1进行AND运算时将产生1。然后将v
移位1位并继续。
答案 4 :(得分:0)
这是计算位数的天真版本。事实上,有很多方法可以更快地计算它。一个简单的解决方案是
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
v &= v - 1; // clear the least significant bit set
}
但是对于速度来说,表查找是最快的。您可以找到许多位计数算法here