【发布时间】:2019-07-30 21:47:04
【问题描述】:
很难完全理解一个基本算法,它接受一个数字 x 并交换位置 i 和 j 的位。这个算法是众所周知的
def swap_bits(x, i, j):
if (x >> i) & 1 != (x >> j) & 1:
bit_mask = (1 << i) | (1 << j)
x ^= bit_mask
return x
据我了解,算法的工作原理是
- 检查位置 i 和 j 的位是否不同。如果没有,我们就完成了 bc 交换相同的位就像什么都不做一样
- 如果它们不同,则我们通过翻转位来交换它们。我们可以使用 XOR 来做到这一点。
我不完全理解的是位掩码的构造是如何工作的。我知道掩码的目标是识别我们想要切换的位子集,但为什么(1 << i) | (x << j) 是这样做的?我想我看到它一秒钟,然后我失去了它。
编辑:
我想我现在看到了。我们只是创建了两个二进制数,一个在i 位置设置了一个位,一个在j 位置设置了一个位。通过 ORing 这些,我们在i 和 j 位置设置了一个数字。我们可以将此掩码应用于我们的输入x,因为x ^ 1 = 0 时x = 1 和1 时x = 0 交换位。
【问题讨论】:
-
为了更有趣,这可以调整为无分支,通过
m = ((x >> i) ^ (x >> j)) & 1和 xoring x by(m << i) | (m << j)。这是同一件事:如果位不同,则m = 1并且两个位都被翻转(交换它们,因为它们不同),如果位没有不同,则m = 0并且没有任何反应。