浮動小数点のオーバーフローとアンダーフロー

浮動小数点計算が表現するには大きすぎる値(オーバーフロー)や小さすぎる値(アンダーフロー)を生成した場合に何が起こるか、IEEE 754がこれらのケースをどう処理するかを理解します。

Precision

Decimal Value

3.4028234663852886e+38

Float32 Hex

0x7F7FFFFF

Float64 Hex

0x47EFFFFFE0000000

詳細な説明

オーバーフローとアンダーフローは、浮動小数点演算の結果が表現可能な範囲外にある場合に発生します。IEEE 754は両方のケースについて特定の動作を定義しています。

オーバーフロー:

結果の絶対値が最大の表現可能な有限値を超えた場合に発生します。

精度 最大有限値 Hex
Float32 3.4028235e+38 0x7F7FFFFF
Float64 1.7976931e+308 0x7FEFFFFFFFFFFFFF

オーバーフローが発生すると、デフォルトの丸めモードでは結果は+Infinityまたは-Infinity(符号による)になります。

一般的なオーバーフローシナリオ:

  • 指数的成長: Math.exp(1000)Infinity
  • 大きな乗算: 1e200 * 1e200Infinity
  • 二乗: (1e200) ** 2Infinity

アンダーフロー:

結果が正規化数として表現するには小さすぎる(ゼロに近すぎる)場合に発生します。IEEE 754は非正規化数による段階的アンダーフローでこれを処理します。

精度 最小正規化 最小非正規化
Float32 1.175e-38 1.401e-45
Float64 2.225e-308 5e-324

最小の非正規化値以下では、結果はゼロにフラッシュされます。

オーバーフローとアンダーフローの検出:

// オーバーフロー検出
if (!isFinite(result)) {
  console.log("オーバーフローが発生");
}

// アンダーフロー検出(近似)
if (result !== 0 && Math.abs(result) < Number.MIN_VALUE) {
  console.log("結果は非正規化(アンダーフロー)");
}

実際にオーバーフローを避ける:

一般的な手法は対数空間で作業することです。a * bを計算する代わりに、log(a) + log(b)を計算します。精度を犠牲にしてオーバーフローを防ぎます。機械学習フレームワークは確率計算でこれを広く使用しています。

ユースケース

オーバーフローとアンダーフローの管理は、科学計算(粒子物理シミュレーション、宇宙論的計算)、機械学習(損失関数計算、softmax)、金融リスクモデル、および非常に大きなまたは非常に小さな数を扱うアプリケーションに不可欠です。

試してみる — IEEE 754 Inspector

フルツールを開く