我试图弄清楚如何读取历史二进制数据文件。我相信它来自较旧的 32 位 Solaris 系统。我正在查看我认为包含 32 位浮点数(不是 IEEE 浮点数)的文件部分。格式似乎是(作为十六进制转储):
xx41 xxxx
xx42 xxxx
这些位置中的 41 和 42 始终通过浮点数出现。恐怕我没有任何额外的信息可以补充。所以我的问题的第一部分是,这是什么格式?如果第一部分不能直接回答,可能的可能性列表会很好。最后,您建议如何确定这是什么格式?谢谢您的意见。
我试图弄清楚如何读取历史二进制数据文件。我相信它来自较旧的 32 位 Solaris 系统。我正在查看我认为包含 32 位浮点数(不是 IEEE 浮点数)的文件部分。格式似乎是(作为十六进制转储):
xx41 xxxx
xx42 xxxx
这些位置中的 41 和 42 始终通过浮点数出现。恐怕我没有任何额外的信息可以补充。所以我的问题的第一部分是,这是什么格式?如果第一部分不能直接回答,可能的可能性列表会很好。最后,您建议如何确定这是什么格式?谢谢您的意见。
这可能是 PDP-11 格式吗?对我来说,赠品是第二个字节大部分是恒定的,这表明浮点格式的指数以第二个字节而不是第一个字节结束(正如您对大端机器所期望的那样)或最后(对于小端机器)。PDP-11 因其有趣的浮点和整数字节顺序而臭名昭著。请参阅此浮点格式页面底部附近的材料。
41
和的值42
似乎与大致单位数量级的正值一致:PDP-11 格式的指数偏差似乎是128
,因此使用不寻常的字节顺序,我希望您列出的第二个字节包含指数的符号和最高 7 位;这将使第二个字节的无偏指数为41
2 或 3,具体取决于第 8 个指数位(应显示为第一个字节的 MSB)。
有关 PDP-11 格式的简要说明,另请参阅此页面。
[编辑] 这是一些 Python 代码,用于将您描述的形式的 4 字节字符串转换为 Python 浮点数,假设 4 字节字符串表示 PDP-11 格式的浮点数。
import struct
def pdp_to_float(xs):
"""Convert a 4-byte PDP-11 single-precision float to a Python float."""
ordered_bytes = ''.join(xs[i] for i in [1, 0, 3, 2])
n = struct.unpack('>I', ordered_bytes)[0]
fraction = n & 0x007fffff
exponent = (n & 0x7f800000) >> 23
sign = (n & 0x80000000) >> 31
hidden = 1 if exponent != 0 else 0
return (-1)**sign * 2**(exponent-128) * (hidden + fraction / 2.0**23)
例子:
>>> pdp_to_float('\x00\x00\x00\x00')
0.0
>>> pdp_to_float('\x23\x41\x01\x00')
5.093750476837158
>>> pdp_to_float('\x00\x42\x00\x00')
16.0
所描述的数据与通常的 IEEE 754 格式一致,以大端顺序存储,然后由小端转储程序一次显示两个字节。
区间 [8, 128) 中的 32 位浮点数的第一个字节为 0x41 或 0x42。考虑这样一个数字,可能是 0x41010203。先存储大端,在内存中会出现四个字节0x41、0x01、0x02、0x03。当转储程序读取 16 字节整数时,小端优先,它将读取并显示 0x0141 和 0x0302。