python:解压缩IBM 32位浮点数 [英] python: unpack IBM 32-bit float point

查看:226
本文介绍了python:解压缩IBM 32位浮点数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在像这样在python中读取二进制文件:

I was reading a binary file in python like this:

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浮点时,我的数据是IBM 32位浮点数

when I realized unpack(">f", str) is for unpacking IEEE floating point, my data is IBM 32-bit float point numbers

我的问题是: 如何隐含unpack来解压缩IBM 32位浮点类型数字?

My question is: How can I impliment my unpack to unpack IBM 32-bit float point type numbers?

我不介意使用像ctypes那样扩展python以获得更好的性能.

I don't mind using like ctypes to extend python to get better performance.

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

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

This looks very promising, but I want to get more efficient: there are potential tens of thousands of loops.

在下面发布答案.谢谢你的提示.

posted answer below. Thanks for the tip.

推荐答案

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

I think I understood it: first unpack the string to unsigned 4 byte integer, and then use this function:

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)

感谢所有提供帮助的人!

Thanks for all who helped!

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

IBM Floating Point Architecture, how to encode and decode: http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture

我的解决方案: 我写了一个类,我认为这样可以更快一些,因为使用了Struct对象,所以解压缩fmt只被编译一次. 这也是因为它一次要解压缩size * bytes,并且解压缩可能是一项昂贵的操作.

My solution: I wrote a class, I think in this way, it can be a bit faster, because used Struct object, so that the unpack fmt is compiled only once. also because it's unpacking size*bytes all at once, and unpacking can be an expensive operation.

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位浮点数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆