Python|浮動小数点の丸め誤差の原因と対策

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における浮動小数点の誤差は避けて通れない課題ですが、正しい知識と道具を使えば、問題を防ぐことができます。特に実務(会計や分析業務など)では、こうした誤差が命取りになることもあるため、意識しておくと安心です。

学習のコツ:浮動小数点の誤差は最初は戸惑いますが、「なぜ起きるのか」を理解することで、落ち着いて対処できるようになります。

タイトルとURLをコピーしました