最後更新日期:2019 年 02 月 21 日
「四捨五入」是約整 (Rounding)的一種方式,在 python 的內建函數中,有一個 round 函數來處理,但是,處理的方式跟我們想像的有點不同。
看一下官方網站對 round 函數的說明:
Return number rounded to ndigits precision after the decimal point. If ndigits is omitted or is None, it returns the nearest integer to its input.
For the built-in types supporting round(), values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done toward the even choice (so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2).
裏面提到了,當要處理的位數,他的值是 5 時,進位值會取最接近的「偶數」。舉例來說:
# 這會印出 2
print(round(1.5))
# 這也會印出 2
print(round(2.5))
這看起來挺不妙的,跟我們實際運用的情形不同。
解決的方法是用 decimal 模組
如果你只是想處理整數位數的四捨五入
from decimal import Decimal, ROUND_HALF_UP
# 這會印出 2
print(Decimal('1.5').quantize(0, ROUND_HALF_UP))
# 這會印出 3
print(Decimal('2.5').quantize(0, ROUND_HALF_UP))
請特別注意,傳入 Decimal 的參數,必須要是字串型態, 否則可能會出現意想不到的狀況。
舉例來說:
from decimal import Decimal, ROUND_HALF_UP, ROUND_UP
# 正確方式
# 這會印出 1.2
print(Decimal('1.15').quantize(Decimal('.1'), ROUND_HALF_UP))
# 這會印出 1.3
print(Decimal('1.25').quantize(Decimal('.1'), ROUND_HALF_UP))
# 錯誤方式!!
# 這會印出 1.1
print(Decimal(1.15).quantize(Decimal('.1'), ROUND_HALF_UP))
# 這會印出 1.3
print(Decimal(1.25).quantize(Decimal('.1'), ROUND_HALF_UP))
# 另一種正確的方式
a = 1.15
b = 1.25
# 這會印出 1.2
print(Decimal(str(a)).quantize(Decimal('.1'), ROUND_HALF_UP))
# 這會印出 1.3
print(Decimal(str(b)).quantize(Decimal('.1'), ROUND_HALF_UP))
如果想要進一步的了解 decimal 模組,可以看一下我的 python – decimal 模組教學
參考資料
1、https://docs.python.org/3/library/functions.html?highlight=round#round
2、https://docs.python.org/2/library/decimal.html#quick-start-tutorial
3、https://stackoverflow.com/questions/33019698/how-to-properly-round-up-half-float-numbers-in-python
Comments