0.1 + 0.2 === 0.3 がfalseになる理由と直し方
浮動小数点数は2進数で表現されるため、0.1や0.2のような10進の小数を正確に表せません。演算結果はごくわずかな誤差を含み、===での比較は失敗します。
なぜエラーが出ないのか
出力: false
(エラーなし)- JavaScriptは何も報告しません。文法として正しいためです
出力: false- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 const price = 0.1 + 0.2; 2 console.log(price === 0.3 ); ^
出力: false期待: true (エラーにはなりません)
0.1と0.2は2進数の浮動小数点数として正確に表せないため、加算結果はわずかに0.3からずれます。厳密な===ではなく、誤差の範囲で比較する必要があります。
直し方: price === 0.3 を Math.abs(price - 0.3) < Number.EPSILON にします。
広告
広告スロット(未設定)
パターン2
1 const total = 1 - 0.9; 2 console.log(total === 0.1 ); ^
出力: false期待: true (エラーにはなりません)
1 - 0.9も浮動小数点の誤差で0.1と厳密には一致しません。減算でも加算と同じ問題が起こります。
直し方: total === 0.1 を Math.abs(total - 0.1) < Number.EPSILON にします。
パターン3
1 const sum = 0.1 * 3; 2 console.log(sum === 0.3 ); ^
出力: false期待: true (エラーにはなりません)
掛け算でも同じ誤差が生じます。0.1 * 3は0.30000000000000004になり、0.3とは===で一致しません。
直し方: sum === 0.3 を Math.abs(sum - 0.3) < Number.EPSILON にします。
よくある誤解
「小数の計算は正確なはず」という前提はJavaScriptに限らずほとんどの言語の浮動小数点数に当てはまりません。厳密な一致ではなく、Number.EPSILONのような小さな許容誤差の範囲で比較する必要があります。
まとめ
0.1 + 0.2 === 0.3 がfalseになる理由と直し方は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。