需要帮助理解 Python 代码
Need help understanding Python Code
请帮助理解以下函数背后的逻辑:
def bit_rev (x, b): # reverse b lower bits of x
return sum (1<<(b-1-i) for i in range (0, b) if (x>>i) & 1)
我看了一下代码,它似乎没有解释第 b 位之后的位。所以,我又加了一个。 (除非你只想要第 b 位):
def bit_rev (x, b): # reverse b lower bits of x
return (x >> b << b) + sum(1 << (b - 1 - i) for i in range (0, b) if (x >> i) & 1)
现在开始解释逻辑。
x >> b << b
因此,假设我们在此示例中使用 5(如 x
),而 2 作为 b
。
5的二进制表示是101
。所以,我们只想切换最后 2 位。即 01
。然而,在我们的其他代码中,我们正在交换它们,但我们忽略了 b 之后的位。所以,我们忽略了第一个(从左到右)1
.
现在第一次操作:
x >> b
在我们的例子中是 5 >> 2
。 101 向右移动 2 是 1
,因为我们最终砍掉了 01
。
- 接下来我们把它移回来。我们保证(在 Python 中)从移位中取回 0,所以我们现在有
100
,或 4.
现在是肉的部分,
sum(1 << (b - 1 - i) for i in range (0, b) if (x >> i) & 1)
在列表理解之外可能更容易理解,所以我将其重写为 for 循环。
summation = 0
for i in range (0, b):
if (x >> i) & 1:
summation += 1 << (b - 1 - i)
基本上,在每次迭代中,我们都会找到反向位,然后将其添加到总数中 (summation
)。
这段代码似乎有点难以理解,因为发生了很多事情。
让我们从 for 循环本身开始。 for i in range (0, b)
遍历 0 和 b 之间的所有值。 (或者你想改变的最后一点)。所有的反转都在稍后的代码中发生。
接下来我们检查要交换的位是否是 1
。在二进制中,只有 1
的值添加到总数中,因此忽略所有 0
是合乎逻辑的。在 if (x >> i) & 1:
。我们将 x 向右移动 i 位。所以,101
位向右移动1位就是10
。我们现在通过 & 1
检查最后一位是否为 1。基本上 & 1
在这个程序中所做的是忽略第一位之后的所有位。
与位运算符的工作原理如下:
0101
&1100
=0100
并且要求两者都为真。由于 1
之后的所有位都为 0,因此它实际上忽略了其余位。
现在我们从 (x >> i) & 1
得到 0 或 1,并且 Python 将所有非零整数处理为 True,将零处理为 False。这将使使用忽略所有为零的位。
接下来,我们使用 summation += 1 << (b - 1 - i)
添加到求和中。我们通过使用 b - 1 - i
获得该位的位置。然后我们将 1 移到该位置,然后将其添加到总数中。
当添加两个二进制整数时,您可以将 1 添加到数字中类似于以 10 为基数的位置。因此,如果我有数字 9000 并且我想要百分之一的数字我可以做9000 + 100。这与我们在这里所做的类似。我们通过使用 <<
运算符而不是采用 10^i 将其移到基数 2 的左侧。所以我们将新反转的位设置为原始位。
请帮助理解以下函数背后的逻辑:
def bit_rev (x, b): # reverse b lower bits of x
return sum (1<<(b-1-i) for i in range (0, b) if (x>>i) & 1)
我看了一下代码,它似乎没有解释第 b 位之后的位。所以,我又加了一个。 (除非你只想要第 b 位):
def bit_rev (x, b): # reverse b lower bits of x
return (x >> b << b) + sum(1 << (b - 1 - i) for i in range (0, b) if (x >> i) & 1)
现在开始解释逻辑。
x >> b << b
因此,假设我们在此示例中使用 5(如 x
),而 2 作为 b
。
5的二进制表示是101
。所以,我们只想切换最后 2 位。即 01
。然而,在我们的其他代码中,我们正在交换它们,但我们忽略了 b 之后的位。所以,我们忽略了第一个(从左到右)1
.
现在第一次操作:
x >> b
在我们的例子中是5 >> 2
。 101 向右移动 2 是1
,因为我们最终砍掉了01
。- 接下来我们把它移回来。我们保证(在 Python 中)从移位中取回 0,所以我们现在有
100
,或 4.
现在是肉的部分,
sum(1 << (b - 1 - i) for i in range (0, b) if (x >> i) & 1)
在列表理解之外可能更容易理解,所以我将其重写为 for 循环。
summation = 0
for i in range (0, b):
if (x >> i) & 1:
summation += 1 << (b - 1 - i)
基本上,在每次迭代中,我们都会找到反向位,然后将其添加到总数中 (summation
)。
这段代码似乎有点难以理解,因为发生了很多事情。
让我们从 for 循环本身开始。 for i in range (0, b)
遍历 0 和 b 之间的所有值。 (或者你想改变的最后一点)。所有的反转都在稍后的代码中发生。
接下来我们检查要交换的位是否是 1
。在二进制中,只有 1
的值添加到总数中,因此忽略所有 0
是合乎逻辑的。在 if (x >> i) & 1:
。我们将 x 向右移动 i 位。所以,101
位向右移动1位就是10
。我们现在通过 & 1
检查最后一位是否为 1。基本上 & 1
在这个程序中所做的是忽略第一位之后的所有位。
与位运算符的工作原理如下:
0101
&1100
=0100
并且要求两者都为真。由于 1
之后的所有位都为 0,因此它实际上忽略了其余位。
现在我们从 (x >> i) & 1
得到 0 或 1,并且 Python 将所有非零整数处理为 True,将零处理为 False。这将使使用忽略所有为零的位。
接下来,我们使用 summation += 1 << (b - 1 - i)
添加到求和中。我们通过使用 b - 1 - i
获得该位的位置。然后我们将 1 移到该位置,然后将其添加到总数中。
当添加两个二进制整数时,您可以将 1 添加到数字中类似于以 10 为基数的位置。因此,如果我有数字 9000 并且我想要百分之一的数字我可以做9000 + 100。这与我们在这里所做的类似。我们通过使用 <<
运算符而不是采用 10^i 将其移到基数 2 的左侧。所以我们将新反转的位设置为原始位。