網頁

2020/12/6

Python 浮點數四捨五入,無條件進位,無條件捨去 floats round up and round down

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 位

若文章對您有幫助還幫忙點個廣告,謝謝您的支持。




沒有留言:

張貼留言