Python

【Python】小数点の切り上げ・切り捨て・四捨五入

この記事では、Pythonで小数点を切り上げ、切り捨て、四捨五入する方法を解説します。

切り上げ

小数点を切り上げるには、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()関数を使います。

round(number[, ndigits])

round()関数は、number引数の小数をndigits引数の桁に丸めた値を返します。ndigits引数を省略するか、Noneだった場合、整数で返されます。

サンプル

試しにround関数を使って適当な値を四捨五入してみましょう!

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進数の分数で表現されているらしい。2進数の分数で10進数の浮動小数点数を表現しているのでどうしてもズレが生じ、このような問題が問題が起こってしまうとのこと。

なので、正確に四捨五入したい場合はround()関数は向いていない。値の正確さが重要な場合は、Decimalクラスを使うか、自作関数を定義しよう!

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クラスを使って四捨五入してみましょう!

from decimal import Decimal, ROUND_HALF_UP

e = 2.71828182846

print(Decimal(str(e)).quantize(Decimal('0.1'), ROUND_HALF_UP))
print(Decimal(str(e)).quantize(Decimal('0.01'), ROUND_HALF_UP))
print(Decimal(str(e)).quantize(Decimal('0.001'), 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クラスを使うという感じでいいと思います。

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ

最短3か月でエンジニア転職『DMM WEBCAMP COMMIT』