「四捨五入」是約整 (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

Last modified: 2019-02-21

Author

Comments

Write a Reply or Comment

Your email address will not be published.