如何在python中获取long的有符号整数值?

时间:2009-09-03 20:54:39

标签: python unsigned signed

如果lv存储一个long值,并且机器是32位,则代码如下:

iv = int(lv & 0xffffffff)

结果是long类型的iv,而不是机器的int。

在这种情况下如何获得(签名)int值?

6 个答案:

答案 0 :(得分:27)

import ctypes

number = lv & 0xFFFFFFFF

signed_number = ctypes.c_long(number).value

答案 1 :(得分:14)

您使用的是高级脚本语言;本质上,您运行的系统的本机数据类型不可见。你不能使用这样的代码强制转换为原生的signed int。

如果您知道要将值转换为32位有符号整数 - 无论平台如何 - 您只需使用简单的数学运算进行转换:

iv = 0xDEADBEEF
if(iv & 0x80000000):
    iv = -0x100000000 + iv

答案 2 :(得分:8)

我可以建议:

def getSignedNumber(number, bitLength):
    mask = (2 ** bitLength) - 1
    if number & (1 << (bitLength - 1)):
        return number | ~mask
    else:
        return number & mask

print iv, '->', getSignedNumber(iv, 32)

答案 3 :(得分:7)

本质上,问题是签名从32位扩展到......无限多位,因为Python有任意大的整数。通常情况下,符号扩展是在转换时由CPU指令自动完成的,因此有趣的是,这在Python中比在C中更难。

通过玩游戏,我发现了类似于BreizhGatch的功能,但这并不需要条件语句。 n & 0x80000000提取32位符号位;然后,-保持相同的32位表示,但对其进行符号扩展;最后,扩展符号位在n上设置。

def toSigned32(n):
    n = n & 0xffffffff
    return n | (-(n & 0x80000000))

Bit Twiddling Hacks提出了另一种可能更为普遍的解决方案。 n ^ 0x80000000翻转32位符号位;然后- 0x80000000将签署 - 延伸相反的位。另一种思考方式是,最初,负数高于正数(以0x80000000分隔); ^交换他们的立场;然后-将负数转移到0以下。

def toSigned32(n):
    n = n & 0xffffffff
    return (n ^ 0x80000000) - 0x80000000

答案 4 :(得分:6)

您可以使用 struct 库来转换这样的值。这很难看,但有效:

from struct import pack, unpack
signed = unpack('l', pack('L', lv & 0xffffffff))[0]

答案 5 :(得分:0)

快速而肮脏的解决方案(在我的情况下,x绝不会超过32位)。

if x > 0x7fffffff:
    x = x - 4294967296