从“无符号”字节流中读取 32 位有符号值
Posted
技术标签:
【中文标题】从“无符号”字节流中读取 32 位有符号值【英文标题】:Read 32-bit signed value from an "unsigned" bytestream 【发布时间】:2012-02-09 18:09:07 【问题描述】:我想从一个文件中提取数据,该文件的信息存储在大端并且总是无符号。从 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 模块的信息。但我仍然对我的实际问题的解决方案感兴趣。
【问题讨论】:
我想你想要结构模块。 以前用过,但没有提供正确的结果。嗯,等等,我想我需要告诉它字节流有什么字节序? xD @jterrace 伙计,我不知道我可以告诉它有关字节序的信息。谢谢 jterrace。但是,我仍然会对解决方案感兴趣。 :) 最高有效位确实定义了数字的符号。我知道您所说的“最左端”是什么意思,但是在谈论大端和小端时会让人感到困惑。 【参考方案1】:我会使用struct。
import struct
def toU32(bits):
return struct.unpack_from(">I", bits)[0]
def toS32(bits):
return struct.unpack_from(">i", bits)[0]
格式字符串“>I”表示从字符串位读取大端“>”、无符号整数“I”。对于有符号整数,您可以使用“>i”。
编辑
必须查看另一个 *** 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)
【讨论】:
感谢您的信息,不知道。 :) 但是,我仍然对硬编码版本感兴趣。【参考方案2】:我会使用struct module's 打包和解包方法。
有关示例,请参阅 Endianness of integers in Python。
【讨论】:
【参考方案3】:toS32(bits) 的无条件版本可能类似于:
def toS32(bits):
decoded = toU32(bits)
return -(decoded & 0x80000000) + (decoded & 0x7fffffff)
当然,您也可以预先计算任何其他位大小的掩码。
【讨论】:
以上是关于从“无符号”字节流中读取 32 位有符号值的主要内容,如果未能解决你的问题,请参考以下文章