Duncan..
58
要获得相当于C cast的值,只需按位并使用适当的掩码.例如,如果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,则此逆过程将保持值不变,但显然它不是真正的逆,因为如果您开始使用的值不适合掩码大小,则这些位将消失.
@MB我扩展了答案,希望能对您有所帮助。 (2认同)