4

我试图弄清楚如何读取历史二进制数据文件。我相信它来自较旧的 32 位 Solaris 系统。我正在查看我认为包含 32 位浮点数(不是 IEEE 浮点数)的文件部分。格式似乎是(作为十六进制转储):

xx41 xxxx
xx42 xxxx

这些位置中的 41 和 42 始终通过浮点数出现。恐怕我没有任何额外的信息可以补充。所以我的问题的第一部分是,这是什么格式?如果第一部分不能直接回答,可能的可能性列表会很好。最后,您建议如何确定这是什么格式?谢谢您的意见。

4

2 回答 2

4

这可能是 PDP-11 格式吗?对我来说,赠品是第二个字节大部分是恒定的,这表明浮点格式的指数以第二个字节而不是第一个字节结束(正如您对大端机器所期望的那样)或最后(对于小端机器)。PDP-11 因其有趣的浮点和整数字节顺序而臭名昭著。请参阅此浮点格式页面底部附近的材料。

41和的值42似乎与大致单位数量级的正值一致:PDP-11 格式的指数偏差似乎是128,因此使用不寻常的字节顺序,我希望您列出的第二个字节包含指数的符号和最高 7 位;这将使第二个字节的无偏指数为412 或 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
于 2012-06-07T13:28:29.590 回答
3

所描述的数据与通常的 IEEE 754 格式一致,以大端顺序存储,然后由小端转储程序一次显示两个字节。

区间 [8, 128) 中的 32 位浮点数的第一个字节为 0x41 或 0x42。考虑这样一个数字,可能是 0x41010203。先存储大端,在内存中会出现四个字节0​​x41、0x01、0x02、0x03。当转储程序读取 16 字节整数时,小端优先,它将读取并显示 0x0141 和 0x0302。

于 2012-06-07T23:32:59.943 回答