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

问题描述 投票:5回答:2

在进行二进制文件写入时,我在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,)

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

python file-io struct binaryfiles
2个回答
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)


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意味着你有一个二进制的重复小数,它永远重复。

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

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

编码的结果是:尽可能晚地计算划分,以防止这些错误在每次计算时累积。

© www.soinside.com 2019 - 2024. All rights reserved.