在进行二进制文件写入时,我遇到了在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,)
附加数字是怎么回事?这是一个舍入误差吗?这是如何工作的?
答案 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的倍数。
那么,现在二进制如何工作?好吧,这很烂,因为除以2的唯一因子是除2以外的所有其他素数将具有永远重复的重复小数-包括十分之一,百分之一等,在分母中都具有5的因数。 1.2345是12345/10000,在分母中具有因子2和5,而5表示您有一个重复的二进制十进制,可以永远重复。
但是你不能永远重复。这意味着您必须将小数点后的数字四舍五入,以使其适合编码您的浮点数的二进制数字。
当您转换回十进制时,将显示舍入误差。
编码的结果是:尽可能晚地计算除法,以防止这些误差在每次计算时不断累积。