表达式含义的逻辑右移(num % 0x100000000) >> 1



在Java中,因为我们有'>>>'用于逻辑右移操作,这在Python中是缺失的。 我遇到过这个表达方式:

(num % 0x100000000) >> 1

我试图理解它是如何工作的并理解它,这样我就不必记住了。

谢谢

该表达式与逻辑移位和算术移位之间的差异关系不大,后者保留符号(当你谈论 2 的补码数时最左边的位)。

在问题中的表达式中,num % 0x100000000只是剥离最右侧 32 位左侧的任何内容,以确保您要移动的值被强制转换为 32 位范围0 - 0xffffffff。然后>> 1向右移动。因为您已经强制了范围,所以即使您的输入值像0xffffffff12345678这样奇怪,您也能保证0移动到最左侧的位。

首先,Python 确实有>>但没有像>>>这样的三重运算符。>>执行按位右移:

https://wiki.python.org/moin/BitwiseOperators

Java 中的>>>运算符将位向右"无符号"移动,这意味着最新的最左边位始终是0位。 ("有符号"移位将复制符号位,因此0位表示正整数值,1位表示负整数值。

Java有一个特定大小的变量的概念:你可以有一个32位整数,或者一个64位整数,等等。 在 Python 中,我们只有int类型的对象,它们是任意精度的(它们具有所需的存储位,因此可以存储非常大的值)。 因此,在您的代码片段中,我们的第一步是确保我们的整数值最大为 32 位。

我不知道你在哪里找到这个例子,但它将模数运算与位移混合在一起。 常数0x1000000002**32. 模数找到除法后剩余的余数。 因此,此模运算将仅保留整数值的最低 32 位。

就个人而言,我会使用逻辑 AND 进行操作:

x & 0xff_ff_ff_ff(请注意,下划线在Python 3.x中是合法的"糖";它们不做任何事情,但我们可以使用它们来分隔数字组。 在这种情况下,我使用它们来分隔字节,以明确这是四个0xff字节串在一起以构成2**32 - 1

此断言不会在我的计算机上触发,因为两个值相等:assert x & 0xff_ff_ff_ff == x % 0x100000000

但是模运算符有一个优点:无论你是在"大端"计算机上还是在"小端"计算机上运行该代码,它都应该提供数字的较低位。 我使用的是 AMD 64 位处理器,即 x86,这意味着它是小端序。 (我实际上不确定按位 AND 如何在大端系统上的 Python 中工作;我在大端系统上有一些使用C的经验,但没有Python的经验。 它实际上可能有效! 但模量肯定会起作用。

因此,在隔离了该值的较低 32 位之后,我们想要右移 1 位。 我们始终需要注意运算符优先级,以确保事情以正确的顺序发生;在这种情况下,显式括号保证在我们只取最低的 32 位之后发生偏移。

当模数抓住较低的 32 位时,结果永远不会是负数:它将是一个介于00xff_ff_ff_ff之间的整数(包括 到 )。 因此,当右移时,高位肯定会是一个0位。 因此,此代码片段保证产生与将整数值放入 Java 32 位整数变量然后使用>>>右移相同的内容。

最新更新