了解数字的奇偶性
Understanding parity of a number
我正在学习 "Elements of Programming Interviews",第一个问题是关于计算数字的奇偶校验(二进制表示中 1 的个数是偶数还是奇数)。提供的最终解决方案是这样做的:
short Parity(unsigned long x) {
x ^= x >> 32;
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x &= 0xf;
...
我知道使用 x 的最终值,您可以在查找 table = 0x6996
中查找答案。但我的问题是为什么上面的代码有效?我已经手工制作了一个 16 位示例,它确实给出了正确的奇偶校验,我只是在概念上不理解它。
之所以有效,是因为
- 单个位的奇偶校验本身(基本情况)
- 位串 x 和 y 的奇偶校验是 x 的奇偶校验和 y 的奇偶校验的异或
这给出了一个递归算法,通过将每个字符串从中间拆分直到它是一个基本情况,然后你可以按层分组并颠倒翻转以获得问题中显示的代码..有点,因为它结束了很早就通过查找完成了最后一步。
查找 table 令人困惑。让我们放下它继续前进:
...
x ^= x >> 2;
x ^= x >> 1;
p = x&1;
为了弄明白,让我们从 1 位的情况开始。在 1 位的情况下,p=x,因此如果 x 为 1,则奇偶校验为奇数,如果 x 为 0,则奇偶校验为偶数。微不足道。
现在是两位大小写。您查看 b0^b1(位 0 XOR 位 1),这就是奇偶校验。如果它们相等,则奇偶校验为偶数,否则为奇数。也很简单
现在让我们添加更多位。在四位示例中 - b3 b2 b1 b0,我们计算 x ^ (x>>2)
,这给了我们一个两位数: b3^b1 b2^b0 。这些是实际的两个奇偶校验 - 一个用于原始数的奇数位,一个用于原始数的偶数位。将两个奇偶异或,我们得到原始奇偶。
现在这对我们来说继续下去,你想要的很多位。
对于n位数x,在z次迭代后,答案总是在x的最右边n/(2的z次方)位。
让我们举一个例子,其中 n=8 和 x=10110001 (b7, b6, b5, b4, b3, b2, b1, b0).
actual/correct答案是even_parity.
1 次迭代后
10110001
00001011
___________
x = 10111010
最右8/(2的1次方)=x的4位=1010(偶校验)
2次迭代后
10111010
00101110
___________
x = 10010100
最右边的8/(2的2次方)=x的2位=00(偶校验)
3次迭代后
10010100
01001010
___________
x = 11011110
最右8/(2的3次方)=x的第1位=0(偶校验)
现在我们可以通过 ANDING 与 a 提取数字 b 的第 d 位
数字 q 其中只有第 d 个数字是 1(一),所有其他数字都是 0(零)。
这里我们要提取x的最终值的(第0位)/(最右位)
所以让我们 AND 它(即,( final_value_of_x
(i.e, 11011110)
)
after (
2 to the power(
log n to the base 2
)
) iterations
) with 00000001 to get the answer.
11011110
00000001
_________________
00000000
我正在学习 "Elements of Programming Interviews",第一个问题是关于计算数字的奇偶校验(二进制表示中 1 的个数是偶数还是奇数)。提供的最终解决方案是这样做的:
short Parity(unsigned long x) {
x ^= x >> 32;
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x &= 0xf;
...
我知道使用 x 的最终值,您可以在查找 table = 0x6996
中查找答案。但我的问题是为什么上面的代码有效?我已经手工制作了一个 16 位示例,它确实给出了正确的奇偶校验,我只是在概念上不理解它。
之所以有效,是因为
- 单个位的奇偶校验本身(基本情况)
- 位串 x 和 y 的奇偶校验是 x 的奇偶校验和 y 的奇偶校验的异或
这给出了一个递归算法,通过将每个字符串从中间拆分直到它是一个基本情况,然后你可以按层分组并颠倒翻转以获得问题中显示的代码..有点,因为它结束了很早就通过查找完成了最后一步。
查找 table 令人困惑。让我们放下它继续前进:
...
x ^= x >> 2;
x ^= x >> 1;
p = x&1;
为了弄明白,让我们从 1 位的情况开始。在 1 位的情况下,p=x,因此如果 x 为 1,则奇偶校验为奇数,如果 x 为 0,则奇偶校验为偶数。微不足道。
现在是两位大小写。您查看 b0^b1(位 0 XOR 位 1),这就是奇偶校验。如果它们相等,则奇偶校验为偶数,否则为奇数。也很简单
现在让我们添加更多位。在四位示例中 - b3 b2 b1 b0,我们计算 x ^ (x>>2)
,这给了我们一个两位数: b3^b1 b2^b0 。这些是实际的两个奇偶校验 - 一个用于原始数的奇数位,一个用于原始数的偶数位。将两个奇偶异或,我们得到原始奇偶。
现在这对我们来说继续下去,你想要的很多位。
对于n位数x,在z次迭代后,答案总是在x的最右边n/(2的z次方)位。 让我们举一个例子,其中 n=8 和 x=10110001 (b7, b6, b5, b4, b3, b2, b1, b0).
actual/correct答案是even_parity.
1 次迭代后
10110001
00001011
___________
x = 10111010
最右8/(2的1次方)=x的4位=1010(偶校验)
2次迭代后
10111010
00101110
___________
x = 10010100
最右边的8/(2的2次方)=x的2位=00(偶校验)
3次迭代后
10010100
01001010
___________
x = 11011110
最右8/(2的3次方)=x的第1位=0(偶校验)
现在我们可以通过 ANDING 与 a 提取数字 b 的第 d 位 数字 q 其中只有第 d 个数字是 1(一),所有其他数字都是 0(零)。
这里我们要提取x的最终值的(第0位)/(最右位)
所以让我们 AND 它(即,( final_value_of_x
(i.e, 11011110)
)
after (
2 to the power(
log n to the base 2
)
) iterations
) with 00000001 to get the answer.
11011110
00000001
_________________
00000000