1. はじめに
Pythonを使って数値計算をしていると、「0.1 + 0.2 が 0.3 にならない」といった現象に出会ったことはありませんか? これは浮動小数点の丸め誤差が原因です。
本記事では、Pythonにおける浮動小数点の丸め誤差の仕組みとその回避方法について、初心者にもわかりやすく丁寧に解説していきます。
具体的なコード例や実行結果も交えながら、誤差を意識したコーディングができるようになることを目指します。
2. 浮動小数点の丸め誤差とは?Pythonでの基本解説
2-1. 浮動小数点数の内部表現
コンピュータは、小数を二進数で表現しますが、一部の小数(例:0.1)は二進数で正確に表現できません。そのため、近似値で記憶され、計算結果にわずかなズレ(丸め誤差)が生じます。
a = 0.1 + 0.2
print(a)
print(a == 0.3)
実行結果:
0.30000000000000004
False
一見正しく見える足し算が、比較するとFalse
になるという現象です。
2-2. Decimal型を使った精度の高い計算
Pythonでは、標準ライブラリdecimal
を使うことで、丸め誤差の少ない十進数計算が可能です。
from decimal import Decimal
a = Decimal('0.1') + Decimal('0.2')
print(a)
print(a == Decimal('0.3'))
実行結果:
0.3
True
このように、Decimal
型では、文字列として数値を渡すことで誤差のない計算が可能になります。
3. よくある使い方・応用例
3-1. Decimal型による金額計算
例えば、家計簿アプリや売上管理システムなどでは、お金の計算における誤差は致命的です。こうした場面ではDecimal
型の使用が推奨されます。
from decimal import Decimal
# 商品AとBの価格
price_a = Decimal('19.99')
price_b = Decimal('34.50')
# 合計金額
total = price_a + price_b
print(f"合計金額: {total} 円")
実行結果:
合計金額: 54.49 円
このように、Decimalを使えば金額の誤差を防ぎ、正確な計算ができます。
3-2. math.isclose() を使った比較
浮動小数点の比較には、math.isclose()
を使う方法もあります。
import math
a = 0.1 + 0.2
b = 0.3
# iscloseで誤差を許容した比較
print(math.isclose(a, b))
実行結果:
True
math.isclose()
は、誤差を含んだ値同士を「実質的に等しい」と判定するために使われます。
4. 注意点・エラー対策
4-1. 浮動小数点をそのまま比較しない
以下のようなコードは正しく動かない場合があります。
# よくあるミス
if 0.1 + 0.2 == 0.3:
print("OK")
実行結果:
(何も出力されない)
これは誤差により条件式がFalse
になるためです。比較にはDecimalやiscloseを使うようにしましょう。
4-2. Decimalの初期化には文字列を使う
Decimal(0.1)
のように直接float型を渡すと、既に誤差を含んだ値が使われてしまいます。
from decimal import Decimal
# float型を渡すと誤差が出る
print(Decimal(0.1)) # NG
print(Decimal('0.1')) # OK
実行結果:
0.1000000000000000055511151231...
0.1
必ず文字列で渡すのがポイントです。
5. まとめ
- 浮動小数点の丸め誤差は、二進数で表せない小数によって起こる。
- Decimal型やmath.isclose()を使うことで、正確な比較・計算が可能になる。
- 金額や精密な数値計算では
float
よりDecimal
を使うのがベスト。
Pythonにおける浮動小数点の誤差は避けて通れない課題ですが、正しい知識と道具を使えば、問題を防ぐことができます。特に実務(会計や分析業務など)では、こうした誤差が命取りになることもあるため、意識しておくと安心です。
学習のコツ:浮動小数点の誤差は最初は戸惑いますが、「なぜ起きるのか」を理解することで、落ち着いて対処できるようになります。