0.2×0.2が0.04000000000000001? Big.jsで精度問題を検証してみた
0.2×0.2が0.04000000000000001? Big.jsで精度問題を検証してみた
はじめに
とある課題で計算機を作ったとき、
「0.2 × 0.2 = 0.04000000000000001」と表示されて混乱しました。
JavaScriptでよく話題になる“浮動小数点誤差”が原因だったのですが、
当時はどう対処していいのか分からず困惑した記憶があります。
この記事では、その誤差をどのように防げるかを Big.js を使って検証してみます。
JavaScriptの浮動小数点誤差とは
JavaScriptでは数値を IEEE754倍精度浮動小数点数 で表現しています。
この方式は2進数で小数を表すため、10進数を正確に表せないことがあります。
例:
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.2 * 0.2); // 0.04000000000000001
これはバグではなく仕様です。
しかし、計算アプリや金額計算などでは致命的な誤差になるため、対策が必要になります。
Big.jsとは
Big.jsは、高精度な小数演算を可能にする軽量なライブラリです。
特徴:
・小数点以下の精度を任意に保持できる
・四則演算・比較・丸めが可能
・依存が少なく軽い(わずか数KB)
同様のライブラリとしては decimal.js, bignumber.js などもありますが、
Big.js はシンプルで扱いやすいのが魅力です。
通常の演算とBig.jsの比較
まずは通常のJavaScriptとBig.jsの違いを見てみます。
console.log(0.2 * 0.2); // 0.04000000000000001
import Big from "big.js";
console.log(Big(0.2).times(0.2).toString()); // 0.04
Big.jsを使うと、正確に 0.04 が得られます。
これは内部で文字列ベースの計算を行っているためです。
Vueで検証用の電卓を作成
今回の検証では、Vueで簡単な電卓アプリを作りました。
・Big.jsを導入して精度を担保
・すべての演算を Big() オブジェクトで実行
デプロイ先はこちら:
🔗 https://vue-calculator-5d7a5.web.app/
GitHub URL:
🔗https://github.com/iwa-ma/vue-calculator
UIはシンプルですが、内部では Big.js を用いた計算処理が行われています。
Big.jsを使う際の注意点
1. 常に文字列で渡す
Big("0.2").times("0.2") // 正確
Big(0.2).times(0.2) // わずかに誤差リスク
浮動小数点を直接渡すと、
初期化の段階で誤差を含んでしまうことがあるため、文字列で渡すのが安全です。
補足:なぜ「文字列で渡す」と安全なのか?
JavaScript の数値は IEEE754 という2進数の浮動小数点形式で表現されます。
この形式では「0.2」や「0.1」のような一見単純な小数も、実際は無限に続く2進数でしか近似できません。
0.2 === 0.2000000000000000111 // 実際には完全一致しない
そのため、Big(0.2) と書いた時点で既に誤差を含んだ値が Big.js に渡ってしまいます。
一方、Big("0.2") は文字列として10進数を正確に読み取るため、誤差を含まず安全です。
2. 型変換に注意
Big.jsの値を途中でNumberに戻してしまうと、再び誤差が生じます。
最後に表示するときだけ .toString() で文字列化しましょう。
補足:Numberに戻すと再び誤差が発生する理由
Big.js は内部で文字列ベースの10進演算を行うため、
演算中は誤差ゼロで「0.1 + 0.2 = 0.3」を正確に計算できます。
しかし、toNumber() や Number() でJavaScriptの通常の数値に変換した瞬間、
再び IEEE754 による2進変換の丸め誤差が発生します。
const x = Big("0.1").plus("0.2");
console.log(x.toString()); // "0.3" 正確
console.log(x.toNumber()); // 0.30000000000000004 誤差復活
このため、表示や比較時は .toString() のまま扱うのが安全です。
まとめ
・JavaScriptの小数計算には浮動小数点誤差がつきもの。
・Big.jsを使えば、精度を保ったまま安全に計算できる。
・金額・単位換算・測定アプリなど、正確さが必要な場面では非常に有効。
Discussion