🐥

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を使えば、精度を保ったまま安全に計算できる。
・金額・単位換算・測定アプリなど、正確さが必要な場面では非常に有効。

参考資料

Big.js GitHub

MDN:浮動小数点数の精度について

Discussion