0.1 + 0.2 が 0.3 にならない理由を図にした

壊れているのではなく、10進で割り切れる数が2進では割り切れないためです。比較の仕方と、金額を扱うときの原則を整理しました。

この記事の結論

  1. 0.1 + 0.2 は 0.30000000000000004 になる
  2. 10進で割り切れる数が、2進では割り切れないため
  3. だから小数を === で比べない
  • 0.1 + 0.2 は 0.30000000000000004 になる
  • 10進で割り切れる数が、2進では割り切れないため
  • だから小数を === で比べない

一度は見たことがあるはずの現象だ。不具合ではなく、数の持ち方から来る必然になる。

実際に出る値

MDNの記載にある例をそのまま引く。

0.1 + 0.2          // 0.30000000000000004
0.1 + 0.2 === 0.3  // false
0.1+0.2の実際の計算結果と、10進では割り切れる数が2進では割り切れないことを帯で示し、許容差を使う比較方法を添えた図
図1:10進では一区切りで表せる数が、2進では表しきれない。打ち切った差が残る。
SPONSORED

なぜそうなるのか

10進では、0.1 は「10等分したうちの1つ」としてきれいに書ける。

ところが計算機の中は2進だ。2進の小数で表せるのは1/2、1/4、1/8……の足し算だけになる。0.1 はこの組み合わせでぴったりにならない。

10進で 1/3 が 0.333… と続いて終わらないのと同じ構造だ。どこかで打ち切るしかなく、打ち切ったぶんの差が残る。

その差を持ったまま足すので、答えがわずかにずれる。

どれくらいの差なのか

この「表せる細かさ」を示す値が用意されている。MDNの説明では、Number.EPSILON は「1と、1より大きな最小の浮動小数点数の差」で、値は2のマイナス52乗、およそ 2.22e-16。

小数点以下16桁目あたりの話になる。画面に出す分には見えないが、等しいかどうかの判定には効く。

だから === で比べない

MDNは明確に書いている。浮動小数点数で === と比較してはいけない。代わりに、十分に近ければ等しいとみなす。

function equal(x, y, tolerance = Number.EPSILON) {
  return Math.abs(x - y) < tolerance;
}

差の絶対値が、決めた許容差より小さければ等しいと判断する形になる。

許容差は数の大きさに合わせる

ここが見落とされやすい。MDNには「浮動小数点数の絶対精度は数が大きくなるにつれ低下する」とあり、大きな数を比べるときは大きさに応じて許容差を調整する必要があると書かれている。

つまり Number.EPSILON をそのまま使えばよい、という話ではない。比較する数の桁に合わせた値を使う。

金額は小数で持たない

実務でいちばん効く結論がこれになる。金額を小数で持つと、足し引きのたびに差が積み上がる。

対策は単純で、最小単位の整数で持つ。円なら円単位の整数、1円未満を扱うなら銭単位の整数にして、表示するときだけ小数に直す。

  • 整数なら足し引きで誤差が出ない
  • 割り算のときだけ、端数の扱いを決めればよい
  • 合計が合わない、という不具合が消える

ほかに気をつけるところ

  • 繰り返し足す処理 — 0.1 を10回足しても1にならない。回数は整数で数える
  • 画面表示 — 桁を丸めて出す。計算結果をそのまま出さない
  • 数値の比較で並べ替え — 等しいとみなす範囲を決めておく

これは特定の言語の問題ではない

同じ現象は、浮動小数点数を使う環境では共通して起きる。言語を変えても解決しない。

AIにコードを書かせたときも同様で、金額の計算を小数のまま書いてくることがある。出てきたコードで最初に見る箇所の1つになる。読む場所の絞り方はエラー文の読み方を覚えたら、AIに頼む回数が減ったと同じ考え方で決められる。

まとめ

  • 0.1 + 0.2 は 0.30000000000000004。不具合ではない
  • 2進で表せるのは 1/2、1/4、1/8… の足し算だけ。0.1 はぴったりにならない
  • Number.EPSILON は 2のマイナス52乗、約 2.22e-16
  • 小数を === で比べない。許容差を使う
  • 許容差は比べる数の大きさに合わせる
  • 金額は最小単位の整数で持つ。表示のときだけ小数にする
SPONSORED

出典

  • MDN「Number.EPSILON」(値、=== で比較しないこと、許容差を使う比較、大きさに応じた調整)

図は本記事のために作成したもの。本記事は2026年10月13日時点の内容に基づく。

新しい記事が出たら、ブラウザの通知でお知らせします。

メールアドレスの登録は要りません。いつでも止められます。

AUTHOR

北海道のWEB屋

北海道を拠点に、Web業界14年・サポート実績1,000件以上。WordPressの復旧、サーバー移転、独自ドメインとメールの設定、PHP・JavaScriptの修正まで対応します。相談と見積もりは無料です。

SPONSORED

関連記事

RELATED