检查是否设置了奇数位的快速方法?

时间:2013-08-13 11:05:57

标签: algorithm integer bit-manipulation xor

我需要确定某个类型的变量(可能是32位无符号或64位无符号)中设置的位数是否为奇数。我读过:

How to count the number of set bits in a 32-bit integer?

这当然非常有用,但我想做得更好,因为我只需要一个二进制答案,而不是整个计数。我想更换一个字节或两个字节的LUT应该非常快,但也许非LUT代码可以以某种方式改进。

3 个答案:

答案 0 :(得分:5)

XOR所有位。为了达到最佳效果,您可以通过将32 MSB与32 LSB进行对齐来将64位数减少为32位数。然后将32位数字减少为16位数字,最后将16位数字减少为8.一旦有了一个字节,就可以使用一个简单的映射表来确定是否有偶数或奇数位。

答案 1 :(得分:4)

纯位解决方案:重复XOR值的下半部分和上半部分,如下所示:

function IsOdd(n)
{
    n ^= n >> 32;
    n ^= n >> 16;
    n ^= n >> 8;
    n ^= n >> 4;
    n ^= n >> 2;
    n ^= n >> 1;
    return (n & 1) == 1;
}

这可以使用预先填充的查找表进行优化:

function Prepopulate()
{
    bool[] answer = new bool[256];
    answer[0] = false;
    for (int i = 1; i < 256; i++)
        answer[i] = answer[i >> 1] ^ ((i & 1) == 1);
}
function IsOdd(n)
{
    n ^= n >> 32;
    n ^= n >> 16;
    n ^= n >> 8;
    return answer[n & 255];
}

您可能希望使用不同的预先填充的表格大小;在我的例子中,我使用了一个8位表(256项)。

答案 2 :(得分:4)

对于现代处理器和gcc编译器:

 IsOdd = __builtin_popcount(value)&1;

或者,正如福尔克所指出的那样,只是:

 IsOdd = __builtin_parity(value);

gcc内置文档here