在python中打包和解包二进制浮点数

时间:2013-04-23 09:15:29

标签: python file-io struct binaryfiles

在进行二进制文件写入时,我遇到了在python中打包和解包二进制浮点数的问题。这就是我所做的:

import struct

f = open('file.bin', 'wb')
value = 1.23456
data = struct.pack('f',value)
f.write(data)
f.close()

f = open('file.bin', 'rb')
print struct.unpack('f',f.read(4))
f.close()

我得到的结果如下:

(1.2345600128173828,)

附加数字是怎么回事?这是一个舍入误差吗?这是如何工作的?

2 个答案:

答案 0 :(得分:7)

在大多数平台上,Python浮点数是C所谓的double,但是您将数据写成float而不是精度的一半。

如果你使用double,你的精确度损失就会减少:

>>> data = struct.pack('d',value)
>>> struct.unpack('d',data)
(1.23456,)
>>> data = struct.pack('f',value)
>>> struct.unpack('f',data)
(1.2345600128173828,)

float结构格式仅提供single precision (24 bits for the significant precision)

答案 1 :(得分:0)

这是一个十进制到二进制的问题。

您知道小数部分在重复吗?例如,1/3永远是0.3333333->。 1/7永远是0.142857142857 [142857]->。

这就是关键所在:重复分数是那些分母的因数不等于10的因数-例如,不是2和/或5的倍数。

  • 1/2平均分配
  • 1/3次重复
  • 1/4平均分配
  • 1/5均分
  • 1/6次重复
  • 1/7重复
  • 1/8均分
  • 1/9重复
  • 1/10平均分配
  • 1/11重复
  • 依此类推

那么,现在二进制如何工作?好吧,这很烂,因为除以2的唯一因子是除2以外的所有其他素数将具有永远重复的重复小数-包括十分之一,百分之一等,在分母中都具有5的因数。 1.2345是12345/10000,在分母中具有因子2和5,而5表示您有一个重复的二进制十进制,可以永远重复。

但是你不能永远重复。这意味着您必须将小数点后的数字四舍五入,以使其适合编码您的浮点数的二进制数字。

当您转换回十进制时,将显示舍入误差。

编码的结果是:尽可能晚地计算除法,以防止这些误差在每次计算时不断累积。