四捨五入就用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.15測試一下:

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章