计算int中的位 - 为什么此代码有效?

时间:2010-10-12 02:08:12

标签: c binary integer bit

我试图了解有关比特的更多信息,但我遇到了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;
}

5 个答案:

答案 0 :(得分:9)

如果设置v & 1中的最低位,则

v为1,如果不设置则为{0>。

循环继续将每次迭代的v位右移1位,因此v的最低位循环遍历原始v中的每个位(如每一个人在“分数”结束之前都会到达1位置。

因此,它循环遍历每个位,如果设置则将c加1,如果不设置则加0,从而总计原始v中的设置位。

例如,v的起始1011

  1. 1011 & 1 = 1,因此c递增为1。
  2. 然后1011转为101
  3. 101 & 1 = 1,因此c递增为2。
  4. 101转为10
  5. 10 & 1 = 0,因此c不会增加并保持为2。
  6. 10转为1
  7. 1 & 1 = 1,因此c增加到3。
  8. 1转为0(因为最后一位从小数结束时掉落)。
  9. 由于for循环的条件只是v,而v现在是0,这是一个假值,循环停止。
  10. 最终结果,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的真值表。

  • 1& 0 = 0
  • 0& 1 = 0
  • 1& 1 = 1

因此,如果来自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