-1

我试图更多地了解位,我遇到了这个例子

此代码如何计算位数?(顺便说一句,我的 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;
}
4

4 回答 4

9

v & 1如果设置了最低位,则为 1,否则为v0。

循环在每次迭代时将右移位除以v1,因此v循环的最低位在原始位的每个位上v(因为每个位在“脱落”小数末端之前到达 1 的位置)。

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

例如,以开头v1011

  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,这是一个假值,循环停止。

最终结果,如我们所愿,c = 3。

于 2010-10-12T02:12:11.653 回答
2

v >>= 1 将继续移动最低有效位,直到 v 全为零。所以我们在把它们都数完之前不要停下来。v&1 测试我们将要移出的位是否为 1,因此我们确保在移出之前对其进行计数。

于 2010-10-12T02:13:09.817 回答
1

v &基本上提取最低有效位v-1如果该位被设置,0如果没有。通过循环的每次迭代它都会v向右移动 1 个位置。并且在每次迭代中,它将该v &测试的结果添加到 counter c。因此,设置的每一位都意味着1添加;添加每个清除位0

于 2010-10-12T02:13:11.290 回答
1

基本上,您将 1 位v与值 1 进行比较,并且您知道 AND 的真值表。

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

因此,如果来自的位v为 1,则与 1 进行与运算将产生 1。然后移位v1 位并继续。

于 2010-10-12T02:13:24.973 回答