Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python:解包IBM 32位浮点_Python_Floating Point_Binary_Ieee 754 - Fatal编程技术网

python:解包IBM 32位浮点

python:解包IBM 32位浮点,python,floating-point,binary,ieee-754,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) 当我意识到解包(“>f”,str

我正在用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)
当我意识到
解包(“>f”,str)
用于解包IEEE浮点时,我的数据是IBM 32位浮点数

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

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

编辑:我做了一些搜索:

这看起来很有希望,但我想提高效率:可能有成千上万个循环

编辑:在下面张贴答案。谢谢你的提示。

我想我明白了: 首先将字符串解压为无符号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浮点体系结构,如何编码和解码:

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

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()

请参阅@aix,是否有需要注意的endianness问题?请重新发布该编辑作为答案,并在两天后接受它。不要给你的问题添加答案。你可能会因为包装逻辑而损失更多的时间。您应该在提出性能声明之前进行基准测试。