计算64位(长整数)整数的位数?

时间:2010-04-25 18:46:48

标签: c# 64-bit bit-manipulation

我已经通过this SO question读了大约32位,但是64位数呢?我应该屏蔽上下4个字节,对32位执行计数,然后将它们加在一起吗?

3 个答案:

答案 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。这是一种可用于任何长度整数的通用算法。