要获得与 C 转换等效的值,只需按位并使用适当的掩码即可。例如如果unsigned long 是 32 位:
>>> i = -6884376
>>> i & 0xffffffff
4288082920
或者如果是 64 位:
>>> i & 0xffffffffffffffff
18446744073702667240
请注意,尽管这为您提供了 C 中的值,但它仍然是一个有符号值,因此任何后续计算都可能给出否定结果,您必须继续应用掩码来模拟32 位或 64 位计算。
这是可行的,因为尽管 Python 看起来将所有数字都存储为符号和大小,但按位运算被定义为处理二进制补码值。 C 以二进制补码形式存储整数,但位数固定。 Python 位运算符作用于二进制补码值,但好像它们有无限数量的位:对于正数,它们向左延伸到无穷大,零,但负数向左延伸。 & 运算符会将左侧的一串 1 更改为零,并只留下适合 C 值的位。
以十六进制显示值可能会使这一点更清楚(我重写了 f 的字符串作为表达式以表明我们对 32 位或 64 位感兴趣):
>>> hex(i)
'-0x690c18'
>>> hex (i & ((1 << 32) - 1))
'0xff96f3e8'
>>> hex (i & ((1 << 64) - 1)
'0xffffffffff96f3e8L'
对于 C 中的 32 位值,正数上升到 2147483647 (0x7fffffff),负数的最高位设置从 -1 (0xffffffff) 下降到 -2147483648 (0x80000000)。对于完全适合掩码的值,我们可以在 Python 中通过使用较小的掩码移除符号位然后减去符号位来反转该过程:
>>> u = i & ((1 << 32) - 1)
>>> (u & ((1 << 31) - 1)) - (u & (1 << 31))
-6884376
或者对于 64 位版本:
>>> u = 18446744073702667240
>>> (u & ((1 << 63) - 1)) - (u & (1 << 63))
-6884376
如果符号位为 0,此逆过程将保持值不变,但显然它不是真正的逆过程,因为如果您从不适合掩码大小的值开始,那么这些位将消失。