浮動小数点 IEEE 754 精度 丸め誤差
なぜ浮動小数点が必要か
整数だけでは、0.5 や 3.14 といった値を表現できない。かといって、すべての小数を正確に表現するには無限のメモリが必要になる。浮動小数点は、有限のビット数で実数を「近似的に」表現する方法である。
IEEE 754
現代のほぼすべてのコンピュータは、IEEE 754 という規格に従って浮動小数点数を表現する。
IEEE 754 の構造
浮動小数点数 = (-1)^符号 × 仮数部 × 2^指数部
・符号部(sign):正負を表す1ビット
・指数部(exponent):2の何乗かを表す
・仮数部(mantissa/fraction):有効数字を表す
| 型 | ビット数 | 符号 | 指数 | 仮数 | 有効桁数(10進) |
|---|---|---|---|---|---|
| 単精度(float) | 32 | 1 | 8 | 23 | 約7桁 |
| 倍精度(double) | 64 | 1 | 11 | 52 | 約15桁 |
精度の問題
10進数の 0.1 は、2進数では無限小数になる(0.0001100110011...)。これを有限ビットで打ち切るため、誤差が生じる。
有名な例:0.1 + 0.2
JavaScriptで 0.1 + 0.2 を計算すると...
結果:0.30000000000000004
0.3 とは等しくない。
特殊な値
IEEE 754 は、通常の数以外にも特殊な値を定義している。
| 値 | 意味 | 発生例 |
|---|---|---|
| +∞, -∞ | 無限大 | 1.0 / 0.0 |
| NaN | Not a Number | 0.0 / 0.0, √(-1) |
| -0 | 負のゼロ | -1.0 / ∞ |
NaNの特徴:NaN == NaN は false。自分自身と等しくない唯一の値。
対処法
許容誤差での比較
浮動小数点の等値比較は、許容誤差(epsilon)を使う。
Math.abs(a - b) < epsilon
整数での計算
金額計算では、円ではなく「銭」単位の整数で扱う。1234円50銭 → 123450(整数)
高精度ライブラリ
任意精度演算が必要な場合は、BigDecimal(Java)、Decimal(Python)などを使用。
実務での応用
WEB開発での応用
金額計算:浮動小数点を避け、整数(最小単位)で計算。表示時に変換。
座標計算:地図APIでの緯度経度は倍精度が必要。
アニメーション:累積誤差に注意。フレーム間の差分で計算。
AI/MLでの応用
勾配消失/爆発:極端に小さい/大きい値が累積する問題。
半精度(FP16):メモリ節約のため16ビット浮動小数点を使用。精度とのトレードオフ。
正規化:数値を一定範囲に収めて、精度を保つ。
深掘りリンク
- Wikipedia: IEEE 754
- 0.30000000000000004.com(各言語の挙動)
- 書籍:「数値計算の常識」伊理正夫
- 次のステップ:数値解析、誤差論