IEEE 754におけるNaNの検出と動作

IEEE 754のNaN(非数)を理解:ビットパターン、quiet NaN vs signaling NaN、自己不等性、JavaScriptなどの言語で正しくNaNを検出する方法。

Special Values

Decimal Value

NaN

Float32 Hex

0x7FC00000

Float64 Hex

0x7FF8000000000000

詳細な説明

NaN(Not a Number)は、未定義または表現不可能な数学演算の結果を表すIEEE 754の特殊値です。他のすべての浮動小数点値とは異なる固有の性質を持っています。

NaNのビットパターン:

NaNは、すべての指数ビットが1にセットされ、少なくとも1つの仮数ビットが非ゼロでエンコードされます。これにより、すべての指数ビットが1で仮数ビットがすべて0のInfinityと区別されます。

タイプ Float32の例 Float64の例
Quiet NaN 0x7FC00000 0x7FF8000000000000
Signaling NaN 0x7FA00000 0x7FF4000000000000

Quiet NaN vs Signaling NaN:

  • Quiet NaN (qNaN): 例外を発生させずに算術演算を通じて伝播します。仮数の最上位ビットが1です。JavaScriptのNaNはこれです。
  • Signaling NaN (sNaN): 算術で使用されると無効操作例外を発生させます。仮数の最上位ビットが0(他の仮数ビットが少なくとも1つセット)。高水準言語ではほとんど使用されません。

NaNを生成する演算:

  • 0 / 0
  • Infinity - Infinity
  • Infinity * 0
  • sqrt(-1)(負の数の平方根)
  • NaNを含む算術: NaN + 1 = NaN

自己不等性の性質:

NaNは自分自身と等しくない唯一のIEEE 754値です:

  • NaN === NaNfalse
  • NaN !== NaNtrue

これは設計によるもので、NaNを検出する方法を提供します: x !== xならxはNaNです。

コードでのNaN検出:

言語 メソッド
JavaScript Number.isNaN(x) または x !== x
Python math.isnan(x)
C/C++ isnan(x) または x != x
Java Double.isNaN(x)

注意: JavaScriptのグローバルisNaN()関数は引数を先に数値に強制変換するため、isNaN("hello")trueを返します。常にNumber.isNaN()を使用してください。

NaNペイロード:

NaNの仮数ビットはペイロード(NaNの原因に関する追加情報)を運ぶことができます。IEEE標準はこれをサポートしていますが、ほとんどの高水準言語はNaNペイロードをプログラマーに公開しません。

ユースケース

適切なNaN処理は、データ処理パイプライン、科学計算、および欠落または無効な数値データを適切に処理する必要があるアプリケーションにおいて不可欠です。NaNの動作を理解することで、複雑な計算を通じたエラーのサイレントな伝播を防ぎます。

試してみる — IEEE 754 Inspector

フルツールを開く