python中的逻辑右移-表达式的含义num%0x100000000>> 1

问题描述

在Java中,因为我们有'>>>'来进行逻辑右移操作,而Python中缺少此操作。 我遇到过这种表达方式:

(num % 0x100000000) >> 1

我试图了解它的工作原理并弄清它的含义,这样我就不必记住。

谢谢

解决方法

该表达式与逻辑移位和算术移位之间的差异无关,后者保留符号(当您谈论二进制数的补码时最左边的位)。

在问题中的表达式中,num % 0x100000000只是剥离最右边32位左侧的所有内容,以确保将要移位的值强制转换为32位范围0 - 0xffffffff。然后>> 1右移。因为您已经强制了该范围,所以即使输入值像0之类的东西,也可以保证将0xffffffff12345678移到最左边的位。

,

首先,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,这意味着它是低位优先的。 (我实际上不确定在大型端系统上Python中按位AND的工作方式;我在大型端系统上具有C方面的经验,但在Python上却没有。它可能确实有效!但是模数肯定可以工作。 )

因此,在隔离了值的低32位之后,我们想要右移1位。我们始终需要注意运算符的优先级,以确保事情以正确的顺序进行;在这种情况下,显式括号可确保仅在占用最低的32位之后进行移位。

当模数获取低32位时,结果永远不会为负:它将是一个介于00xff_ff_ff_ff之间的整数。因此,当右移时,高位肯定会是0位。因此,保证该代码段产生的效果与将整数值放入Java 32位整数变量然后使用>>>右移一样。