这个浮点格式是什么?

时间:2012-06-07 11:40:03

标签: binary floating-point binaryfiles

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

xx41 xxxx
xx42 xxxx

这些位置的41和42在浮点数上始终如一。我担心我没有任何其他信息可以添加到此。所以我的问题的第一部分是,这是什么格式?如果第一部分无法直接回答,那么可能的可能性列表就会很棒。最后,您如何建议确定这是什么格式?感谢您的投入。

2 个答案:

答案 0 :(得分:4)

这可能是PDP-11格式吗?对我来说,赠品是第二个字节大部分是常量,这表明浮点格式的指数最终在第二个字节而不是第一个字节(正如你所期望的那样) big-endian机器)或最后一台(用于小端机器)。 PDP-11因浮动和整数的有趣字节顺序而臭名昭着;查看此Floating-Point Formats页面底部附近的资料。

4142的值似乎与大致单位幅度的正值一致:PDP-11格式的指数偏差似乎为128,因此对于不寻常的字节顺序,我希望你列出的第二个字节包含符号和指数的最高7位;这将使41的第二个字节的无偏指数为2或3,具体取决于第8个指数位(应该显示为第一个字节的MSB)。

有关PDP-11格式的简要说明,另请参阅this page

[编辑]以下是一些Python代码,用于将您描述的形式的4字节字符串转换为Python float,假设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

答案 1 :(得分:3)

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

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