python:解压缩 IBM 32 位 float

标签 python floating-point binary ieee-754

我正在用 python 读取二进制文件,如下所示:

from struct import unpack

ns = 1000
f = open("binary_file", 'rb')

while True:
    data = f.read(ns * 4)
    if data == '':
        break
    unpacked = unpack(">%sf" % ns, data)
    print str(unpacked)

当我意识到 unpack(">f", str) 是解包 IEEE float 时,我的数据是 IBM 32 位 float

我的问题是: 如何实现我的unpack 以解包 IBM 32 位浮点类型数字?

我不介意使用像 ctypes 来扩展 python 以获得更好的性能。

编辑:我做了一些搜索: http://mail.scipy.org/pipermail/scipy-user/2009-January/019392.html

这看起来很有前途,但我想提高效率:可能有数万个循环。

编辑:在下面发布答案。感谢您的提示。

最佳答案

我想我明白了: 首先将字符串解压缩为无符号 4 字节整数,然后使用此函数:

def ibm2ieee(ibm):
    """
    Converts an IBM floating point number into IEEE format.
    :param: ibm - 32 bit unsigned integer: unpack('>L', f.read(4))
    """
    if ibm == 0:
        return 0.0
    sign = ibm >> 31 & 0x01
    exponent = ibm >> 24 & 0x7f
    mantissa = (ibm & 0x00ffffff) / float(pow(2, 24))
    return (1 - 2 * sign) * mantissa * pow(16, exponent - 64)

感谢所有帮助过的人!

IBM Floating Point Architecture,如何编码和解码: http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture

我的解决方案: 我写了一个类,我觉得这样可以快一点,因为使用了Struct对象,所以unpack fmt只编译一次。 编辑:还因为它一次解包 size*bytes,而且解包可能是一项昂贵的操作。

from struct import Struct

class StructIBM32(object):
    """
    see example in:
    http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture#An_Example

    >>> import struct
    >>> c = StructIBM32(1)
    >>> bit = '11000010011101101010000000000000'
    >>> c.unpack(struct.pack('>L', int(bit, 2)))
    [-118.625]
    """
    def __init__(self, size):
        self.p24 = float(pow(2, 24))
        self.unpack32int = Struct(">%sL" % size).unpack
    def unpack(self, data):
        int32 = self.unpack32int(data)
        return [self.ibm2ieee(i) for i in int32]
    def ibm2ieee(self, int32):
        if int32 == 0:
            return 0.0
        sign = int32 >> 31 & 0x01
        exponent = int32 >> 24 & 0x7f
        mantissa = (int32 & 0x00ffffff) / self.p24
        return (1 - 2 * sign) * mantissa * pow(16, exponent - 64)

if __name__ == "__main__":
    import doctest
    doctest.testmod()

关于python:解压缩 IBM 32 位 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7125890/

相关文章:

python - 列表的自定义字符串表示取决于项目数 (Python)

delphi - 我的 key 的二进制和十六进制字符串表示之间的差异是 DCPCrypt 意外输出的原因吗?

python - 不赞成进位的二进制加法

python - 如何在 python 中通过正则表达式替换/修改模式?

Python:暂停函数但不是整个程序

python - 确定列表中一列最长字符串长度的最快方法

floating-point - clang/gcc 只用 -ffast-math 生成 fma;为什么?

c# - 为什么在这个例子中使用 float 比使用 double 慢 2 倍?

c++ - visual studio 2012 中的 float 和 double 类型

javascript - 评估javascript base 10 to base 2转换函数