浮動小数点数で表現できる最小値より小さい値は、コンピュータが「0」として扱います。これがアンダーフローです。値を小さくしていって、いつ「ゼロに丸められる」のかを確かめましょう。
アンダーフローとは、浮動小数点数で表せる最小値よりさらに小さい値を扱おうとしたとき、その値が「0」として丸められてしまう現象のことです。
浮動小数点数(IEEE 754 単精度)では、ゼロより大きい最も小さい正の値は、おおよそ 1.4 × 10⁻⁴⁵ です。これより小さい正の値は表現する手段がないので、結果として 0 に置き換わります。
身近な例で考えると、ものさしの最小目盛より小さい長さは「0」と読むしかないのと同じです。コンピュータの「ものさし」(浮動小数点表現)にも目盛の限界があり、その下は測れません。
アンダーフローは「絶対値がとても小さい値を扱う」場面で発生します。典型例は次の3つです。
| 発生場面 | なぜ起きる | 対策 |
|---|---|---|
| 非常に小さい数の掛け算 | 小さい数同士を掛けると、結果がさらに小さくなる | 対数空間で計算する(log を使う) |
| 除算で小さい結果 | 大きい数で小さい数を割ると極端に小さくなる | 順序を入れ替えて中間値を抑える |
| 確率の積 | 多数の小さい確率を掛け合わせると指数的に小さくなる | 対数を取って和に変換する |
実務でよく目にするのは機械学習の確率計算です。たとえば100個の小さい確率(それぞれ0.01)を掛け合わせると、結果は 10⁻²⁰⁰。これは単精度では完全に0になります(倍精度でもギリギリ)。だから機械学習のコードでは「対数尤度(log-likelihood)」を使い、確率の積を対数の和に変換するのが定石です。
上のツールでスライダーを 1e-39 あたりまで下げると「非正規化数」の領域に入ります。ここでは値は表せますが、ケチ表現の「先頭の1」が使えなくなるので精度が落ちます。さらに 1e-46 以下になると、完全に0として扱われます。
オーバーフローとアンダーフローは対になる現象です。同じ「表現可能な範囲を超える」問題でも、超え方が逆向きです。
違いの整理:
・オーバーフロー: 絶対値が大きすぎて表せない → 通常は ∞(無限大)として扱われる
・アンダーフロー: 絶対値が小さすぎて表せない → 通常は 0 として丸められる
・どちらも計算精度が失われる点では同じだが、結果が出る方向が異なる
ポイントの整理:
・アンダーフローが発生するのは、表現範囲の下限を下回るとき
・オーバーフローとの違いは、大小の向きが逆で、結果の振る舞いも異なる点
・対策としては、対数空間での計算、スケール変更、より精度の高い型への切り替えなどがある
上のツールで 1e-50 を選ぶと、値は完全に0として処理されます。「データが存在したのに消えてしまう」──これがアンダーフローの怖さです。整数のオーバーフローほど目立つエラーにならないため、気づかずバグを見落とすこともあります。