2012-02-10 509 views
20

我如何能圓了一個數字,小數點後第三位在Python例如:四捨五入到小數點後第三位在Python

0.022499999999999999

應該四捨五入到0.03

0.1111111111111000

應舍入爲0.12

如果在小數點後第三位有任何值,我希望它總是向上舍入,讓我留下2個值小數點

+4

在繼續之前,我建議閱讀Python教程中的[Floating Point Arithmetic:Issues and Limitations](http://docs.python.org/tutorial/floatingpoint.html)。 – 2012-02-10 17:44:25

+0

另外,考慮你是否真的想舍入值,或者你只是想*顯示* 3位小數...... – geoffspear 2012-02-10 19:27:16

回答

17
from math import ceil 

num = 0.1111111111000 
num = ceil(num * 100)/100.0 

參見:
math.ceil documentation
round documentation - 你可能會想反正檢查了這一點以備將來參考

+0

這裏你不需要'round()' - 它不會改變結果以任何方式。 – 2012-02-10 17:49:45

+2

給出下列情況下錯誤的結果: 'math.ceil((1.11 * 100.0))/ 100.0' 出來是'1.12' 因爲: '1.11 * 100.0'具有價值'111.00000000000001' – nimeshkiranverma 2017-02-23 15:59:58

+1

@nimeshkiranverma請參閱[浮點數學是否被破壞?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken)使用['decimal'模塊](https://docs.python.org /3/library/decimal.html)如果你需要精確的小數結果。 – 2017-11-16 14:16:33

34

的Python包括round()功能,lets you specify你想要位數。從文檔:

round(x[, n])

返回浮點值X小數點後四捨五入到n個數字。如果省略n,則默認爲零。結果是一個浮點數。數值四捨五入爲10的最接近倍數,以功率減n;如果兩個倍數同樣接近,則四捨五入從0開始(例如,round(0.5)爲1.0,round(-0.5)爲-1.0)。

所以你想用round(x, 2)做正常的四捨五入。爲確保數字總是舍入爲以上您需要使用ceil(x)函數。同樣,要將下調使用floor(x)

+4

很好的建議,但它並沒有像OP那樣需要**。 – NPE 2012-02-10 17:45:53

+1

「舍入」與正常舍入不同。看看問題中的例子。 – 2012-02-10 17:46:23

+0

你是對的 - 我現在正在編輯。 – simchona 2012-02-10 17:48:14

10
x = math.ceil(x * 100.0)/100.0 
+1

在我意識到這比我的解決方案更加pythonic之前,我不得不盯着這一段時間。 – Edwin 2012-02-10 17:49:53

9

從埃德溫的回答推斷:

from math import ceil, floor 
def float_round(num, places = 0, direction = floor): 
    return direction(num * (10**places))/float(10**places) 

要使用:

>>> float_round(0.21111, 3, ceil) #round up 
>>> 0.212 
>>> float_round(0.21111, 3)  #round down 
>>> 0.211 
>>> float_round(0.21111, 3, round) #round naturally 
>>> 0.211 
+1

在以下情況下給出錯誤結果: 'math.ceil((1。11 * 100.0))/ 100.0' 出來是'1.12' 因爲: '1.11 * 100.0'的值是'111.00000000000001' – nimeshkiranverma 2017-02-23 15:59:28

3

注意,ceil(num * 100)/100招會崩潰一些退化的投入,像1e308。這可能不會經常出現,但我可以告訴你,這花了我幾天的時間。爲了避免這種情況,「如果ceil()floor()採用了小數位參數,就好像round()一樣......」同時,任何人都知道一個乾淨的替代品,它不會像這樣的輸入崩潰?我曾經爲decimal包一些希望,但它似乎死過:

當然
>>> from math import ceil 
>>> from decimal import Decimal, ROUND_DOWN, ROUND_UP 
>>> num = 0.1111111111000 
>>> ceil(num * 100)/100 
0.12 
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP)) 
0.12 
>>> num = 1e308 
>>> ceil(num * 100)/100 
Traceback (most recent call last): 
    File "<string>", line 301, in runcode 
    File "<interactive input>", line 1, in <module> 
OverflowError: cannot convert float infinity to integer 
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP)) 
Traceback (most recent call last): 
    File "<string>", line 301, in runcode 
    File "<interactive input>", line 1, in <module> 
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>] 

之一可能會說,崩潰是這樣的投入,唯一理智的行爲,但我認爲這不是舍入而是乘法這就是導致問題的原因(這就是爲什麼,例如,1e306不會崩潰的原因),並且更清楚地實現第n個地方的fn將避免乘法破解。

+0

這個使用'Decimal'的問題就是結果量化表達式需要311位數字來表示,而且當前精度太小。如果你從''''''''進行了十進制輸入getcontext; getcontext()。prec = 400',這將「工作」,對於某些「工作」值。或者你可以注意到,絕對值大於2 ** 52的浮點數必須是一個整數,所以舍入將不起作用。是的,我同意如果「ceil」和「floor」取小數點的話,這很好。 – 2015-08-30 16:56:33

7

這取決於您在考慮正數和負數時想要的行爲,但是如果您希望始終舍入較大的值(例如2.0449 - > 2.05,-2。0449 - > -2.04),那麼你可以這樣做:

round(x + 0.005, 2) 

還是有點票友:

def round_up(x, place): 
    return round(x + 5 * 10**(-1 * (place + 1)), place) 

這也似乎工作如下:

round(144, -1) 
# 140 
round_up(144, -1) 
# 150 
round_up(1e308, -307) 
# 1.1e308 
0

中規定的輪funtion不不適用於像definate整數:

一個= 8
輪(A,3)
8.0
α= 8.00
輪(A,3)
8.0
一個= 8.000000000000000000000000
輪(A,3)
8.0

但,適用於:

R = 400/3.0
ř
133.33333333333334
圓(R,3)
133.333

Morever小數點如2.675四捨五入爲2.67 n ot 2.68。
更好地使用上面提供的其他方法。