[英]Unexpected floating-point representations in Python
您好我在Python中使用字典存儲一些城市及其人口:
population = { 'Shanghai' : 17.8, 'Istanbul' : 13.3, 'Karachi' : 13.0, 'mumbai' : 12.5 }
現在,如果我使用命令print population
,我得到結果:
{'Karachi': 13.0, 'Shanghai': 17.800000000000001, 'Istanbul': 13.300000000000001, 'mumbai': 12.5}
而如果我使用命令print population['Shanghai']
我得到17.8
的初始輸入。
我的問題是17.8
和13.3
分別如何變成17.800000000000001
和13.300000000000001
? 所有這些信息是如何產生的? 為什么它存儲在那里,因為我的初始輸入表示我不需要額外的信息,至少據我所知。
這已在Python 3.1中更改。 從什么是新的頁面:
Python現在使用David Gay的算法來查找不會改變其值的最短浮點表示。 這應該有助於緩解圍繞二進制浮點數的一些混淆。
使用像
1.1
這樣的數字很容易看出它的重要性,它在二進制浮點數上沒有精確的等價物。 由於沒有確切的等價,因此像float('1.1')
這樣的表達式求值為最接近的可表示值,十六進制為0x1.199999999999ap+0
或十進制為1.100000000000000088817841970012523233890533447265625
。 該最近的值仍然用於后續浮點計算。新的是如何顯示數字。 以前,Python使用了一種簡單的方法。
repr(1.1)
的值計算為format(1.1, '.17g')
,其評估為'1.1000000000000001'
。 使用17位數字的優點是它依靠IEEE-754保證確保eval(repr(1.1))
完全往返到其原始值。 缺點是許多人發現輸出令人困惑(將二進制浮點表示的內在限制誤認為是Python本身的問題)。
repr(1.1)
的新算法更智能並返回'1.1'
。 實際上,它會搜索所有等效的字符串表示形式(使用相同的基礎浮點值存儲的字符串表示形式)並返回最短的表示形式。新算法在可能的情況下傾向於發出更清晰的表示,但它不會改變基礎值。 所以,仍然是
1.1 + 2.2 != 3.3
的情況,即使表示可能另有說明。新算法依賴於底層浮點實現中的某些功能。 如果未找到所需的功能,將繼續使用舊算法。 此外,文本pickle協議通過使用舊算法確保跨平台可移植性。
(供稿人:Eric Smith和Mark Dickinson; issue 1580 )
您需要了解浮點數在計算機中的工作原理。
基本上,並非所有十進制數都可以准確存儲,在這種情況下,您將獲得最接近的數字。 有時這種抽象泄漏,你會看到錯誤。
這可能是由於您描述的兩個用例的打印邏輯存在差異。 我無法重新生成行為(在Win64中使用Python 2.7.2)。
如果你使用一個數字 ,精確表示,如1.5
,我猜走開的效果。
如果要在世界上任何一台機器上指定完全相同的小數,則必須使用decimal.Decimal。
有關信息,請參閱Python手冊: http : //docs.python.org/library/decimal.html
>>> from decimal import Decimal
>>> print Decimal('3.14')
3.14
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.