我试图更多地了解位,我遇到了这个例子。
此代码如何计算位数?(顺便说一句,我的 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;
}
v & 1
如果设置了最低位,则为 1,否则为v
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。
v >>= 1 将继续移动最低有效位,直到 v 全为零。所以我们在把它们都数完之前不要停下来。v&1 测试我们将要移出的位是否为 1,因此我们确保在移出之前对其进行计数。
v &
基本上提取最低有效位v
-1
如果该位被设置,0
如果没有。通过循环的每次迭代它都会v
向右移动 1 个位置。并且在每次迭代中,它将该v &
测试的结果添加到 counter c
。因此,设置的每一位都意味着1
添加;添加每个清除位0
。
基本上,您将 1 位v
与值 1 进行比较,并且您知道 AND 的真值表。
因此,如果来自的位v
为 1,则与 1 进行与运算将产生 1。然后移位v
1 位并继续。