0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Python】四捨五入処理の落とし穴

Last updated at Posted at 2022-11-01

目的

 本記事の目的は筆者自身がPythonの四捨五入に躓き、学習と同時に作成している。
また、Pythonの四捨五入するための構文を控えておくための記事である。

Pythonの四捨五入はどのように記述すれば良いか

 まずは結論としてPythonにおける四捨五入記述を下に記す。
decimalモジュールを使用して四捨五入を処理している。

pythonにおける四捨五入の記述例①:小数点以下第1位を四捨五入
from decimal import Decimal, ROUND_HALF_UP    # 「import *」 でも可
a = 2.5
round_a = Decimal(a).quantize(Decimal('0'), rounding=ROUND_HALF_UP)
print(a, round_a)
2.5 3
pythonにおける四捨五入の記述例②:小数点以下第3位を四捨五入
from decimal import Decimal, ROUND_HALF_UP
b = 1.005
round_b = Decimal(b).quantize(Decimal('0.001'), rounding=ROUND_HALF_UP)
print(b, round_b)
1.005 1.01

ただし、上記四捨五入結果 round_a, round_b の型はdecimal.Decimalとなっているため、int型やfloat型と演算する際には注意が必要である。
その場合はfloat(round_A)のように型の変換を組み込む必要がある。

Pythonのround関数は四捨五入ではない

四捨五入について

 Pythonにて数値計算をする際、下記のようなround関数を使用したことがあるのではないだろうか

round関数の記述例
value1 = round(5.4, 0)
value2 = round(5.5, 0)
value3 = round(6.4, 0)
value4 = round(6.5, 0)

しかしながら、Pythonのround関数は俗に言う四捨五入と呼ばれる処理ではない。
偶数丸め(銀行丸め)と呼ばれる処理であるため、時には四捨五入を期待して実装したプログラムが意図しない挙動を起こす。

round関数記述例の出力
print(value1, value2, value3, value4) 
# それぞれ 5.4, 5.5, 6.4, 6.5
5.0 6.0 6.0 6.0

上記の出力例では、5.4, 5.5, 6.4は問題なく四捨五入が行われているが、6.5については切り捨て処理が行われている。これは偶数丸めによって偶数になるように切り上げ、切り捨てが選択されているためである。

decimalモジュールについて

 では、どのように記述すれば四捨五入が可能になるか。最もシンプルな方法は、decimalというモジュールを使用する方法と思われる。

decimalモジュールとは

 decimalモジュールは十進数計算を正確に表現するために用いられるPythonの標準ライブラリの一種である。

 コンピュータは2進数で計算を実行しているため、出入力の際は人が日常的に用いている10進数から変換、または10進数へ変換する必要がある。
10進数の浮動小数点型から2進数の浮動小数点型へ変換すると、基本的に無理数となってしまうため、正確に表現できないことが多い。そして、無理数を無理数のまま計算に用いることはできないため、ある程度で切った値を用いるが、この切った値を再び10進数に再変換するときにズレが生じる。
ズレ例:1.1 + 2.2 = 3.3000000000000003

10進数 2進数
1 0001
2 0010
3 0011
123 0111 1011
123.456 0111 1011.0111 0100…

decimalモジュールはこのズレが発生しないように正確に計算するためのモジュールである。

decimalモジュールのメソッド

 decimalモジュールのメソッドの一部を下に記す。

メソッド名 説明
quantize() 位を固定して数値を丸め込む。
getcontext() 現在のDecimal型の演算環境設定を出力する。
setcontext() 現在のDecimal型の演算環境設定を書き換える。

参考記事

0
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?