2014-04-30 83 views
0

我正在使用ceil()函數將浮點計算的結果四捨五入到最接近的整數。不同的輸入種種都經歷過......ceil()函數不返回期望值

int(ceil(A*B)) 

這裏有一些例子來說明這個問題:

int(ceil(1.01*100)) = 101 
int(ceil(1.02*100)) = 102 
int(ceil(1.03*100)) = 103 
int(ceil(1.04*100)) = 104 
int(ceil(1.05*100)) = 105 
int(ceil(1.06*100)) = 106 
int(ceil(1.07*100)) = 107 
int(ceil(1.08*100)) = 108 
int(ceil(1.09*100)) = 110 *** 
int(ceil(1.10*100)) = 111 *** 
int(ceil(1.11*100)) = 112 *** 
int(ceil(1.12*100)) = 113 *** 
int(ceil(1.13*100)) = 113 

我意識到這是與浮點運算做正...

執行
1.09*100 = 109.000000.... > 109 

我不知道如何捕獲這個bug可靠

雖然我有一對夫婦的「粗」的方法,如一個概述如下,我不認爲這是一個足夠強大的解決方案

int(ceil((1.09*100)-0.00000001)) = 109 
+5

根據數字來自哪裏,您可能需要查看['Decimal'](https://docs.python.org/2/library/decimal.html)模塊。只要輸入'1.09'已經是'1.0900000000000001' – mhlester

回答

3

你的問題既不是新的,也不是python特定的,但它是浮點計算固有的。所有曾經使用Fortran 4的dynosaurus都知道它:you作爲程序員必須知道預期的精度ε的計算。所以:

  • 兩個數x和y是被視爲等於如果| x - y | < ε
  • 的最大整數不如x是floor(x + ε)
  • 的最小整數大於x是ceil(x - ε)

所以您提出的解決方案是一個很好的解決方案,前提是您有一種方法可以知道什麼是最好的價值。如果你正在編寫一個模塊,你應該允許用戶指定它。

+0

好玩的技巧歡呼。目前它會很方便,只有浮點數字的表示可用。這讓我想起了我對CAD應用程序的編程,因此必須始終精確地測試兩點的重合。 –

+0

爲了一個好的,簡潔的解釋而歡呼。 (巧合的是,這也將一些舊的Fortran轉換爲CAD應用程序) –

2

你是對的,這個問題在浮動的精度有限起源數。

decimal模塊是你的朋友:

from decimal import Decimal 
from math import ceil 

print int(ceil(Decimal("1.10") * 100)) 

注意,那你真的要提供作爲串號,否則它是第一個被Python解析爲浮點數(在這裏,我們用精度得到了問題,我們想避免)。

+0

我已經開始讀取到十進制模塊,指針 –