IEEE 754の非正規化数(サブノーマル数)

ゼロと最小の正規化浮動小数点数の間のギャップを埋め、段階的アンダーフローを可能にする非正規化数(サブノーマル数)について学びます。

Special Values

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. 正規化値は指数が最小(1)に達するまで縮小
  2. さらなる縮小は仮数ビットを右にシフトし、精度を徐々に失う
  3. 数値は非正規化になる — 精度がゼロに向かって滑らかに低下
  4. すべての仮数ビットがゼロになると、値は正確にゼロになる

パフォーマンスに関する考慮事項:

一部のプロセッサ(特に古い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コンピュートシェーダー(デノーマルがゼロにフラッシュされる場合がある)、浮動小数点サポートが限られた組み込みシステム、およびゼロ付近の非常に小さな値が重要なアプリケーションで重要です。

試してみる — IEEE 754 Inspector

フルツールを開く