我试图找到一个位串的奇偶校验,这样如果x的奇数为0,它就会返回1。 我只能使用基本的按位运算,到目前为止我通过了大部分测试,但我想知道两件事:
为什么x ^(x + ~1)有效?我偶然发现了这个问题,但如果有奇数个位,那么它似乎会给你1,如果是偶数则会给你一些东西。像7 ^ 6 = 1,因为7 = 0b0111
这是解决问题的正确方向吗?我假设我的问题源于第一次操作,特别是(x + ~1),因为它会溢出某些2的补码数。感谢
代码:
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;
}
答案 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");
}
}