计数位数:这条线如何工作? N = N及(N-1);

时间:2013-03-12 19:21:54

标签: c++ algorithm bitcount

我需要解释这条特定线路的工作原理 我知道这个函数计算1位的数量,但这条线究竟是如何清除最右边的1位?

int f(int n) {
    int c;
    for (c = 0; n != 0; ++c) 
        n = n & (n - 1);
    return c;
}

有些人可以简单地向我解释一下或给出一些“证明”吗?

2 个答案:

答案 0 :(得分:16)

任何无符号整数'n'将具有以下最后k个数字:一个后跟(k-1)个零:100 ... 0 注意k可以是1,在这种情况下没有零。

(n - 1)将以此格式结束:零后跟(k-1)1:011 ... 1

n&因此,(n-1)将以'k'零结束:100 ... 0& 011 ... 1 = 000 ... 0

因此n& (n - 1)将消除最右边的'1'。每次迭代都会基本上删除最右边的'1'数字,因此你可以计算1的数字。

答案 1 :(得分:3)

我一直在梳理位操作并遇到了这个问题。它现在可能对原版海报(3年后)没用,但我还是要回答其他观众提高质量。

n & (n-1)等于零是什么意思?

我们应该确保我们知道,因为这是打破循环的唯一方法(n != 0)。 我们说n=8。该位的表示将是00001000n-1(或7)的位表示为00000111&运算符返回两个参数中设置的位。由于0000100000000111没有设置任何类似的位,因此结果为00000000(或零)。 您可能已经发现,数字8并非随机选择。这是n是2的幂的一个例子。所有2的幂(2,4,8,16等)将具有相同的结果。

当你传递的指数不是2的指数时会发生什么?例如,当n=6时,位表示为00000110n-1=500000101&适用于这两个参数,它们只有一个共有4位,现在,n=4不是零,所以我们增加c并尝试使用n=4进行相同的处理。正如我们在上面看到的,4是2的指数,因此它将在下一次比较中打破循环。 它会切断最右边的位,直到n等于2的幂。

什么是c

每个循环只增加一个并从0开始。c是在数字等于2的幂之前截断的位数。