1. 程式人生 > >四捨五入就用round( )?Python四捨五入的正確開啟方式!

四捨五入就用round( )?Python四捨五入的正確開啟方式!

round( )函式簡介

菜鳥教程中介紹到,round() 函式作用就是,返回浮點數x的四捨五入值。

> round( x [, n]  )

引數x,n均為數值表示式,返回值為x的四捨五入值。n為保留的小數位數,不加n則只保留x四捨五入後的整數部分。

>>> round(2.3)
2
>>> round(2.45, 1)
2.5

特殊情況

上面的結果並沒有錯誤,這裡再用2.675測試一下:

>>> round(2.675, 2)
2.67

顯然結果不符合四捨五入的規則。為什麼會這樣呢?原因是:round()函式只有一個引數,不指定位數的時候,返回一個整數,而且是最靠近的整數,類似於四捨五入,當指定取捨的小數點位數的時候,一般情況也是使用四捨五入的規則,但是碰到.5的情況時,如果要取捨的位數前的小數是奇數,則直接捨棄,如果是偶數則向上取捨。

這也就解釋了上述現象。可這樣一來用round()函式取浮點數的四捨五入值不就變得不可靠了嘛?這樣的函式設計的意義何在?網上搜了一圈答案,覺得這個說法比較準確:

python3(注意python2 和 3的round()是不一樣的,這裡僅以python3作說明)中round()對浮點數的取捨遵循的是“四捨六入五平分”,“五平分”就是根據取捨的位數前的小數奇偶性來判斷,奇偶平分,符合公平性原則(四捨五入不是公平的),這樣一來也就保證了在資料量較大的情況下,篩選資料的真實性。(數學渣,不知道這樣理解對否……)

為什麼需要平分呢?原因就是部分小數無法用二進位制完整表示,如1.15,轉為二進位制將是很長的一串數字:1.0010011001100110011001100110011001100110011001100110011

這可不是簡單的幾個位元組就能存放下的。因此這裡就出現了取捨的問題。

那麼正確的四捨五入是否無法實現了呢?當然是有解決辦法的。比如,當你需要四捨五入保留兩位小數的時候,可以將數值乘以100再除以100.0:

>>> round(2.675 * 100)/100.0
2.68

這樣可以解決部分浮點數四捨五入的問題。為什麼是部分呢?筆者發現:

>>> round(2.135*100)/100.0
2.13

黑人問號

檢驗下過程:

>>> 2.135*100
213.49999999999997

WTF!是精度問題嘛!

>>> Decimal(2.135)*100
Decimal('213.4999999999999786837179272')

愣住

無法理解是不是!!二進位制的世界正常人真的不懂,盼望一下未來有可以直接計算十進位制的硬體誕生吧。

總結

在用round()函式進行四捨五入時,如果你對結果有十足把握,並且這就是你想要的結果,那就放心大膽地使用。不然就老老實實寫個函式來實現吧,這不是什麼難事。