2012-08-08 69 views
0

可能重複:
python - decimal place issues with floats
Python float equality weirdnessPython的怪異除了錯誤

在下面的代碼我有可變percentage這是一個浮子。我已經建立了這樣,如果number達到10,000,percentage是假設上漲.01

# Tries to find a number that when squared and 5%'ed is still a square. 

import math 

print("Script has started:\n") 

percentage = .1 
number = 1 
while number != -1: 
    number = number + 1 
    num_powered = number ** 2 
    num_5per = num_powered * percentage 
    num_5per_sqrt = math.sqrt(num_5per) 
    num_list = list(str(num_5per_sqrt)) 
    dot_location = num_list.index(".") 
    not_zero = 0 
    for x in num_list[dot_location + 1:]: 
     if x != "0": 
      not_zero = 1 
      break 
    if not_zero == 0: 
     print("*********************************") 
     print("Map :",number) 
     print("Safe-Area :",num_5per_sqrt) 
     print("Percentage :",percentage) 
     print("*********************************") 
     input() 

    if number > 10000: 
       number = 0 
       percentage = percentage + .01 
       print(percentage) 

輸出:

0.11 
0.12 
0.13 
0.14 
0.15000000000000002 # Here is where it goes crazy 
0.16000000000000003 
+4

這是非常普遍的。計算機中的浮點數是基數2,並且它們不能精確地表示基數爲10的許多數字。 – 2012-08-08 20:59:15

+3

這不是一個錯誤。這是浮點變量如何工作的結果。請參閱http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html。投票結束重複。 – 2012-08-08 20:59:56

+0

哦,我看到了感謝,然後抱歉Google搜索,但沒有看到重複。 – RandomPhobia 2012-08-08 21:01:37

回答

11

the Python docs

注意,這是在二進制浮點的本質:這是不是Python中的錯誤,這是不是在你的代碼,通過(重點煤礦)的錯誤。你會看到這樣的事情在支持您的硬件浮點運算(雖然有些語言可能沒有默認顯示的差異,或者在所有輸出模式)的所有語言

你應該使用the decimal module

+4

這個鏈接是對這個現象的非常好的解釋,我以前從未見過。我建議任何人仍然感到困惑應該閱讀它的整體。 – 2012-08-08 21:05:37

6

您使用浮點數,並已經歷了representation error。特別是,0.01沒有精確表示爲二進制浮點數。相反,一個非常接近但不完全等於0.01的數字將被存儲。這不是一個錯誤。這只是浮點算法的工作方式。

您可以通過幾種方式解決您的問題。

  • 接受的結果並不完全準確或
  • 一切乘以100,並正與整數或
  • 使用Decimal型。

例子:

from decimal import Decimal 
percentage = Decimal('0.1') 
step = Decimal('0.01') 
percentage += step 
+1

+1列出解決此問題的常用方法。 – 2012-08-08 21:20:38

0

浮標沒有無限的精度,所以你會得到這樣怪異的行爲。

更好的解決方案是將您的百分比存儲爲整數,表示百分之零點零增量。

如:

percent_as_integer += 1 

,而不是

percent_as_float += 0.01 

當你要顯示的比例,簡單地做:

print "%d.%02d" % divmod(percent_as_integer, 100) 

編輯:其實,使用十進制模塊,而不是作爲在另一個答案中提出的可能是更好的,更pythonic的解決方案。

0

正如其他答案所述,這是所有當前微處理器中本地浮點數的限制。

如果您需要十進制數的精確表示(例如,用於會計和業務應用程序),則應使用decimal類型,而不是浮點型。您也可以使用cdecimal模塊,這是十進制類型的高性能實現。