Pythonで、小数部を四捨五入するround関数の使い方です。(Pythonの標準関数です。)
四捨五入とは
数値の桁を5未満なら切り捨て、5以上なら切り上げる計算のことです。
round関数の使い方
round(number[,ndigits])
numberの小数部をndigits桁で四捨五入した値を返します。
ndigitsが省略された場合は、入力値に最も近い整数を返します。
# -*- coding: utf-8 -*-
f=1.23456789
# 桁数ごとの四捨五入
print(round(f,1))
print(round(f,2))
print(round(f,3))
print(round(f,4))
print(round(f,5))
print(round(f,6))
print(round(f,7))
print(round(f,8))
実行結果は以下のようになります。
1.2
1.23
1.235
1.2346
1.23457
1.234568
1.2345679
1.23456789
この数値(1.23456789)は正しく四捨五入が出来ました。
ただ、公式ページの注釈に心配な内容が記載されています。
「浮動小数点数に対するround()の振る舞いは意外なものかもしれません:例えば、 round(2.675, 2)
は予想通りの 2.68
ではなく 2.67
を与えます。これはバグではありません。: これはほとんどの小数が浮動小数点数で正確に表せないことの結果です。」
なんと、2.675を2桁目で四捨五入すると2.68になるはずですが、この計算が出来ないと記載されています。さらに、これはバグではないとのこと。いろいろな事情があるのかもしれませんが、数学的に正しい計算が出来ないのにバグではないと言われても困りますね。
正しい結果を返す計算方法は、decimalモジュールを使う方法です。以下にコードを記載します。
# -*- coding: utf-8 -*-
from decimal import Decimal, ROUND_HALF_UP
# roundで正確に値を表現できないケース
print(round(0.5))
print(round(1.5))
print(round(2.5))
print(round(3.5))
print(round(4.5))
print(round(2.675,2))
# 対策
print(Decimal("0.5").quantize(Decimal("0"), ROUND_HALF_UP))
print(Decimal("1.5").quantize(Decimal("0"), ROUND_HALF_UP))
print(Decimal("2.5").quantize(Decimal("0"), ROUND_HALF_UP))
print(Decimal("3.5").quantize(Decimal("0"), ROUND_HALF_UP))
print(Decimal("4.5").quantize(Decimal("0"), ROUND_HALF_UP))
print(Decimal("2.675").quantize(Decimal("0.01"), ROUND_HALF_UP))
実行結果は以下のようになります。
0
2
2
4
4
2.67
1
2
3
4
5
2.68
roundで正しく計算できなかった項目が、decimalモジュールで正しく計算できることがわかりました。
ここまで確認してみると、round関数は使えませんね。誤差が出てもいい計算なんか普通はしませんよね。
ということで四捨五入にはround関数は使わず、decimalモジュールでの計算がお勧めとなります。