奇数位的位奇偶校验码

时间:2011-09-23 14:30:01

标签: c bit-manipulation bit parity

我试图找到一个位串的奇偶校验,这样如果x的奇数为0,它就会返回1。 我只能使用基本的按位运算,到目前为止我通过了大部分测试,但我想知道两件事:

  1. 为什么x ^(x + ~1)有效?我偶然发现了这个问题,但如果有奇数个位,那么它似乎会给你1,如果是偶数则会给你一些东西。像7 ^ 6 = 1,因为7 = 0b0111

  2. 这是解决问题的正确方向吗?我假设我的问题源于第一次操作,特别是(x + ~1),因为它会溢出某些2的补码数。感谢

  3. 代码:

    int bitParity(int x) {
        int first = x ^ (x + ~1);
        int second = first ^ 1; // if first XOR gave 1 you'll return 0 here
        int result = !!second;
    return result;
    }
    

3 个答案:

答案 0 :(得分:4)

你的奇偶校验功能实际上并没有实际工作 - 它似乎在一半的时间内得到了答案,这与返回随机结果(甚至只返回0或1)一样好时间)。

实际上有以下几个级别的黑客攻击:http://graphics.stanford.edu/~seander/bithacks.html#ParityNaive - 你可能想看看最后一个:http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel

答案 1 :(得分:3)

我会使用实际计数而不是利用数字表示的位级黑客,这样会感觉更安全,更干净,更容易理解。当然可能比较慢,但这是一个相当不错的权衡,特别是当人们对性能预期一无所知时。

对此,只需编写代码来计算1位数,最直接的解决方案通常归结为循环。

更新:鉴于(奇怪且令人讨厌的)限制,我的回复可能是unwind"naive"解决方案bithacks解决方案中给出的回复页。这不会很漂亮,但我可以做一些有用的事情。 :)

答案 2 :(得分:1)

比特奇偶校验可以这样做:

#include <stdio.h>

int parity(unsigned int x) {
    int parity=0;
    while (x > 0) {
       parity = (parity + (x & 1)) % 2;
       x >>= 1;
    }
}

int main(int argc, char *argv[]) {
    unsigned int i;
    for (i = 0; i < 256; i++) {
        printf("%d\t%s\n", i, parity(i)?"odd":"even");
    }
}