IEEE 754の非正規化数(サブノーマル数)
ゼロと最小の正規化浮動小数点数の間のギャップを埋め、段階的アンダーフローを可能にする非正規化数(サブノーマル数)について学びます。
Decimal Value
1.4e-45
Float32 Hex
0x00000001
Float64 Hex
0x36A0000000000000
詳細な説明
非正規化数(サブノーマル数とも呼ばれる)は、ゼロ付近の極めて小さな数値を表現するIEEE 754浮動小数点値の特殊なカテゴリです。ゼロと最小の正規化数の間の突然のギャップの代わりに、段階的アンダーフローを提供するために存在します。
非正規化数の条件:
浮動小数点数は、バイアス付き指数フィールドがすべてゼロで仮数が非ゼロの場合に非正規化されます。正規化数とは異なり、非正規化数は暗黙の先頭ビットが1ではなく0です。
| プロパティ | 正規化 | 非正規化 |
|---|---|---|
| 指数ビット | 1〜254(float32) | 0 |
| 暗黙のビット | 1 | 0 |
| 計算式 | (-1)^s x 1.仮数 x 2^(指数-バイアス) |
(-1)^s x 0.仮数 x 2^(1-バイアス) |
最小のfloat32値:
- 最小正規化:
2^-126 ≈ 1.175e-38(指数=1、仮数=0) - 最小非正規化:
2^-149 ≈ 1.401e-45(指数=0、最下位仮数ビット=1)
非正規化数がなければ、0から1.175e-38まで表現可能な値のないギャップが存在します。
段階的アンダーフロー:
値が小さくなる過程を考えてみましょう:
- 正規化値は指数が最小(1)に達するまで縮小
- さらなる縮小は仮数ビットを右にシフトし、精度を徐々に失う
- 数値は非正規化になる — 精度がゼロに向かって滑らかに低下
- すべての仮数ビットがゼロになると、値は正確にゼロになる
パフォーマンスに関する考慮事項:
一部のプロセッサ(特に古いx86 CPUと一部のARMコア)では、非正規化数の演算は正規化数よりも大幅に遅くなります(10〜100倍遅いことも)。これは「デノーマルペナルティ」と呼ばれます。一部のアプリケーションでは、段階的アンダーフローの損失を受け入れて、FTZ(flush-to-zero)フラグを設定してパフォーマンスのために非正規化結果をゼロとして扱います。
値1.4e-45(最小のfloat32サブノーマル):
16進数表現0x00000001は指数=0で、最下位の仮数ビットのみがセットされています。これは0.000...001 x 2^(-126) = 2^(-149) ≈ 1.401e-45を表します。
ユースケース
非正規化数の理解は、数値ライブラリの開発、GPUコンピュートシェーダー(デノーマルがゼロにフラッシュされる場合がある)、浮動小数点サポートが限られた組み込みシステム、およびゼロ付近の非常に小さな値が重要なアプリケーションで重要です。