从" unsigned"读取32位有符号值。字节流

时间:2012-02-09 18:09:08

标签: python endianness sign

我想从一个文件中提取数据,该文件信息存储在big-endian中,总是无符号。从 unsigned int int “cast”如何影响实际的十进制值?我是否纠正了最左边的位决定该值是正还是负?

我想用python解析那个文件格式,读取和无符号值很容易:

def toU32(bits):
    return ord(bits[0]) << 24 | ord(bits[1]) << 16 | ord(bits[2]) << 8  | ord(bits[3])

但相应的 toS32 函数将如何显示?


感谢您提供有关 struct -module的信息。但我仍然对我的实际问题的解决方案感兴趣。

3 个答案:

答案 0 :(得分:8)

我会使用struct

import struct

def toU32(bits):
    return struct.unpack_from(">I", bits)[0]

def toS32(bits):
    return struct.unpack_from(">i", bits)[0]

格式字符串“&gt; I”表示从字符串位读取大端,“&gt;”,无符号整数,“I”。对于有符号整数,您可以使用“&gt; i”。

修改

不得不看另一个StackOverflow answer来记住如何从python中的无符号整数“转换”有符号整数。虽然它不是转换,而是更多地重新解释这些位。

import struct

def toU32(bits):
        return ord(bits[0]) << 24 | ord(bits[1]) << 16 | ord(bits[2]) << 8  | ord(bits[3])

def toS32(bits):
    candidate = toU32(bits);
    if (candidate >> 31): # is the sign bit set?
        return (-0x80000000 + (candidate & 0x7fffffff)) # "cast" it to signed
    return candidate


for x in range(-5,5):
    bits = struct.pack(">i", x)
    print toU32(bits)
    print toS32(bits)

答案 1 :(得分:0)

我会使用struct module's打包和解包方法。

有关示例,请参阅Endianness of integers in Python

答案 2 :(得分:0)

toS32(位)的非条件版本可能类似于:

def toS32(bits):
    decoded = toU32(bits)
    return -(decoded & 0x80000000) + (decoded & 0x7fffffff)

当然,您也可以为任何其他位大小预先计算掩码。