2016-08-30 55 views
1

使用「結構包和解包」浮點數0.01輸出0.009999999776482582。 對於我的項目,我將不得不配置浮點數爲 和相同的需要存儲在二進制文件,我需要這些數據以後分析,我需要配置的確切值。使用struct pack並解壓浮點數爲0.01的輸出0.009999999776482582。

如果有任何方法可以存儲精確值0.01並檢索相同的值,有人能幫助我嗎?

基於一些帖子,我已經嘗試使用雙而不是浮動,它的工作原理,但使用雙的問題是我的文件大小增加。我有很多參數,它們是浮點數,可以取0到5之間的任何值。因此,任何其他建議都將不勝感激。

下面是示例代碼

import struct 
a = 0.01 
b = struct.pack('<f', a) 
c = struct.unpack('<f', b) 
print c 
(0.009999999776482582,) 
+1

確切值「0.01」不能由浮動。也許你可以看看'decimal'模塊,如果你想精確地表示'0.01'。 –

+0

你存儲了什麼樣的值?你說數字從0到5有多少個小數位? – vz0

+4

「基於一些帖子,我已經嘗試過使用double而不是float,它可以工作,但使用double的問題是我的文件大小增加了」 - 如果您不願意支付存儲價格來保存所有精度,需要,你不應該抱怨輸出中的精確損失。 – user2357112

回答

2

沒有浮點數0.01。 IEEE浮點數不代表整個實數行;它們表示使用特定二進制方案的近似值。最接近的近似值具有十進制表示形式0.009999999776482582。

您可以嘗試序列化文本表示(例如json)或醃製可表示任意精度的BigDecimal。

2

你說數字從0到5.如果你只需要兩位小數(0.00,0.01,...,5.00),那麼你可以將數字存儲爲16位整數,首先將數字乘以100 ,然後讀除以100的號碼時:

>>> import struct 
>>> digits = 2 
>>> a = 0.01 
>>> b = struct.pack('<H', int(round(a, digits)) * (10 ** digits)) 
>>> c = struct.unpack('<H', b) 
>>> print (c[0]/(10.0 ** digits)) 
0.01 

與H格式存儲號碼相比,花車實際上你可以節省50%的空間。如果您需要更高的精度,兩位以上的小數位,則需要乘以數字,然後除以1000,10000等,將格式從H更改爲I.

+0

'int(a * 100)'將向下舍入,如果'a'爲0.009999999,可能會給出錯誤的結果。 – interjay

+0

這個技巧工作的主要條件是讓數字最多有兩位,只有兩位有效數字。這意味着我不期望有像0.009這樣的數字。這就是爲什麼我問他正在處理的那種數字。 – vz0

+0

這些數字是浮點數,因此不準確會導致像0.01這樣的數字變成0.0099999999。你應該四捨五入到最近的數字而不是四捨五入。 – interjay