Python 對浮點數做四捨五入,無條件進位,無條件捨去的方式如下。
Python的round()函式可以做四捨五入,但「五入」的規則和以前學的數學不太一樣。當進位數剛好是一半例如5時是往最近的偶數進位。
例如round(15, -1),第二個參數-1代表要進位的精確位數為小數點前二位,也就是十進位,取到十進位的結果為20,因為個位數5進位最近的偶數為十位數2。
print(round(15, -1)) # 20
round(25, -1)取到十進位的結果也是20,因為個位數5進位最近的偶數為十位數2。
print(round(25, -1)) # 20
round(35, -1)取到十進位的結果是40,因為個位數5進位最近的偶數為十位數4。
print(round(35, -1)) # 40
但在round()處理浮點數後的小數進位時狀況又不太一樣。例如round(2.15, 1)取到小數點後一位,小數點後二位數5進位最近的偶數為小數點後一位2,但結果卻為2.1。
print(round(2.15, 1)) # 2.1
造成這現象的原因是浮點數無法以二進位精確儲存。雖然浮點數表面上是2.15但使用format()印出小數點後二十位實際上為2.14999999999999991118,小數點後二位數其實是4,所以就捨去成為2.1。
print(format(2.15, '.20f')) # 2.14999999999999991118
為避免以上問題,用round處理浮點數的四捨五入時,可改用Decimal物件來定義精確浮點數值。
from decimal import Decimal
d = Decimal('2.15')
print(round(d, 1)) # 2.2
print(format(d, '.20f')) # 2.15000000000000000000
至於無條件進位及無條件捨去就沒以上問題。
無條件進位用math.cell(),
無條件捨去用math.floor()。
如果要指定進位的小數點後指定位數,則先把原本要進位的數乘上10的指定位數方的值,然後再除以該值的浮點數。
例如無條件進位,無條件捨去至小數點後2位數,則把原本要進位的數乘上102 也就是100,然後再除以100.0。
import math
f = 1.234
print(math.ceil(f * 1) / 1.0) # 2.0 無條件進位至小數點後 0 位
print(math.ceil(f * 10) / 10.0) # 1.3 無條件進位至小數點後 1 位
print(math.ceil(f * 100) / 100.0) # 1.24 無條件進位至小數點後 2 位
print(math.floor(f * 1) / 1.0) # 1.0 無條件捨去至小數點後 0 位
print(math.floor(f * 10) / 10.0) # 1.2 無條件捨去至小數點後 1 位
print(math.floor(f * 100) / 100.0) # 1.23 無條件捨去至小數點後 2 位
若文章對您有幫助還幫忙點個廣告,謝謝您的支持。
沒有留言:
張貼留言