この記事では、Pythonで小数を切り上げ、切り捨て、四捨五入する方法を解説します。
切り上げ | math.ceil() |
---|---|
切り捨て | math.floor() |
四捨五入 | round() または Decimal.quantize() |
四捨五入は、値が正確じゃなくていいならround()
関数を使い、正確に取得したい場合はDecimal.quantize()
を使うという感じでいいと思います。
それでは、もう少し詳しく見ていきましょう!
小数点を切り上げるには、math
モジュールのceil()
関数を使います。math
モジュールは、標準ライブラリなのでインポートするだけで使えます。
import math
math.ceil(x)
ceil()
関数は、x
引数以上の最小の整数を返します。
import math
print(f'1.1 = {math.ceil(1.1)}')
print(f'1.9 = {math.ceil(1.9)}')
print(f'0.5 = {math.ceil(0.5)}')
# 型を調べてみる
print(type(math.ceil(1.1)))
実行結果
1.1 = 2
1.9 = 2
0.5 = 1
<class 'int'>
四捨五入ではなく切り上げな点に注意してください。
小数点を切り捨てるには、math
モジュールのfloor()
関数を使います。
import math
math.floor(x)
floor()
関数は、x
引数以下の最大の整数を返します。
import math
print(f'{1.1} = {math.floor(1.1)}')
print(f'{1.9} = {math.floor(1.9)}')
print(f'{0.5} = {math.floor(0.5)}')
実行結果
1.1 = 1
1.9 = 1
0.5 = 0
必ず切り捨てられる点に注意してください。
四捨五入をするには、複数の選択肢があるのでそれぞれ見ていきましょう!
簡単に四捨五入するには、組み込み関数であるround()
関数を使います。
round(number[, ndigits])
round()
関数は、number
引数の小数をndigits
引数の桁に丸めた値を返します。ndigits
引数を省略するかNone
だった場合、整数で返されます。
print(f'{1.1} = {round(1.1)}')
print(f'{1.9} = {round(1.9)}')
print(f'{0.5} = {round(0.5)}')
実行結果
1.1 = 1
1.9 = 2
0.5 = 0
先ほどのサンプルコードで「0.5」をround()
関数で処理したら「0」になっていました。実はround()
関数は、端数が「0.5」より小さいなら切り捨て、端数が「0.5」より大きいならは切り上げ、端数が「0.5」なら結果が偶数となる方へ丸められます。
print(f'{0.5} = {round(0.5)}')
print(f'{1.5} = {round(1.5)}')
print(f'{2.5} = {round(2.5)}')
print(f'{3.5} = {round(3.5)}')
実行結果
0.5 = 0
1.5 = 2
2.5 = 2
3.5 = 4
また、小数第二位以下では偶数に丸められないこともある。
print(f'{0.05} = {round(0.05, 1)}')
print(f'{0.15} = {round(0.15, 1)}')
print(f'{0.25} = {round(0.25, 1)}')
print(f'{0.35} = {round(0.35, 1)}')
実行結果
0.05 = 0.1
0.15 = 0.1
0.25 = 0.2
0.35 = 0.3
浮動小数点数は、計算機内部で2進数の分数で表現されています。なのでどうしてもズレが生じ、このような問題が起こってしまう。
正確に四捨五入したい場合はround()
関数は向いていない。値の正確さが重要な場合は、Decimal
クラスを使うか自作関数を定義した方が安全です!
Decimal
クラスは、正確に10進数を扱えるクラスで四捨五入もできます。decimal
モジュールは標準ライブラリなのでインポートするだけで使えます。
正確な10進数でオブジェクトを生成するには、str
型で値を指定します。
import decimal
# 正確な10進数の0.5でインスタンス化
d = decimal.Decimal('0.5')
print(d)
実行結果
0.5
Decimal
クラスで四捨五入するにはquantize()
メソッドを使います。
Decimal.quantize(exp, rounding=None, context=None)
exp
引数に、Decimal
クラスを使って求めたい桁数と同じ桁の値を指定します。
rounding
引数には、丸めモードをdecimal
モジュールの定数を使って指定します。丸めモードについては以下のリンクを参考にしてください。
Link丸めモード - decimal --- 十進固定及び浮動小数点数の算術演算 — Python ドキュメント
四捨五入したい場合は、ROUND_HALF_UP
を指定しましょう!
from decimal import Decimal, ROUND_HALF_UP
e = 2.71828182846
print(Decimal(str(e)).quantize(Decimal('1.0'), ROUND_HALF_UP))
print(Decimal(str(e)).quantize(Decimal('1.00'), ROUND_HALF_UP))
print(Decimal(str(e)).quantize(Decimal('1.000'), ROUND_HALF_UP))
実行結果
2.7
2.72
2.718
四捨五入は以下のような感じで定義できる。
def my_round(num, digit=0):
p = 10 ** digit
r = (num * p * 2 + 1) // 2 / p
if digit == 0:
r = int(r)
return r
試しに先ほどの関数を使ってみます。
def my_round(num, digit=0):
p = 10 ** digit
r = (num * p * 2 + 1) // 2 / p
if digit == 0:
r = int(r)
return r
print(f'1.1 = {my_round(1.1)}')
print(f'1.9 = {my_round(1.9)}')
print(f'0.5 = {my_round(0.5)}')
print(f'0.01 = {my_round(0.01, 1)}')
print(f'0.19 = {my_round(0.19, 1)}')
print(f'0.05 = {my_round(0.05, 1)}')
実行結果
1.1 = 1
1.9 = 2
0.5 = 1
0.01 = 0.0
0.19 = 0.2
0.05 = 0.1
この記事では、小数点を切り上げ、切り捨て、四捨五入する方法を解説しました。
切り上げと切り捨ては単純でしたが四捨五入は意外とゴチャゴチャしていました。値が大体でいいならround()
関数を使い、正確に欲しい場合はDecimal.quantize()
を使いましょう!
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ
View Comments