我已经通过this SO question读了大约32位,但是64位数呢?我应该屏蔽上下4个字节,对32位执行计数,然后将它们加在一起吗?
答案 0 :(得分:29)
您可以在此处找到64位版本http://en.wikipedia.org/wiki/Hamming_weight
就像这样
static long NumberOfSetBits(long i)
{
i = i - ((i >> 1) & 0x5555555555555555);
i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333);
return (((i + (i >> 4)) & 0xF0F0F0F0F0F0F0F) * 0x101010101010101) >> 56;
}
这是代码格式的64位版本How to count the number of set bits in a 32-bit integer?
使用约书亚的建议我会将其转化为:
static int NumberOfSetBits(ulong i)
{
i = i - ((i >> 1) & 0x5555555555555555UL);
i = (i & 0x3333333333333333UL) + ((i >> 2) & 0x3333333333333333UL);
return (int)(unchecked(((i + (i >> 4)) & 0xF0F0F0F0F0F0F0FUL) * 0x101010101010101UL) >> 56);
}
编辑:我在测试32位版本时发现了一个错误。我添加了丢失的括号。总和应该在bitwise&,在最后一行
之前完成EDIT2 为ulong
添加了更安全的版本答案 1 :(得分:7)
快速(比使用非标准编译器扩展更便携)方式:
int bitcout(long long n)
{
int ret=0;
while (n!=0)
{
n&=(n-1);
ret++;
}
return ret;
}
每次执行n&=(n-1)
时,都会消除n
中的最后一个设置位。因此,这需要O(设置位数)时间。
这比你测试每一位所需的O(log n)要快 - 除非数字是0xFFFFFFFFFFFFFFFF
,否则不是每一位都被设置,因此通常你需要的迭代次数要少得多。
答案 2 :(得分:6)
C#中的标准答案:
ulong val = //whatever
byte count = 0;
while (val != 0) {
if ((val & 0x1) == 0x1) count++;
val >>= 1;
}
这会将val
向右移一位,如果最右边的位置位,则递增count
。这是一种可用于任何长度整数的通用算法。