JavaのNaN

JavaのNaN

1. 概要

簡単に言えば、NaNは、「数値ではない」を表す数値データ型の値です。

このクイックチュートリアルでは、JavaのNaN値と、この値を生成または関連付けることができるさまざまな操作について説明します。

2. NaNとは何ですか?

NaN usually indicates the result of invalid operations.たとえば、ゼロをゼロで除算しようとすることは、そのような操作の1つです。

We also use NaN for unrepresentable values.値(i)は複素数でしか記述できないため、-1の平方根はそのようなケースの1つです。

IEEE Standard for Floating-Point Arithmetic (IEEE 754)は、NaNの値を定義します。 In Java, the floating-point types float and double implement this standard.

Javaは、floatタイプとdoubleタイプの両方のNaN定数をFloat.NaNDouble.NaNとして定義します。

A constant holding a Not-a-Number (NaN) value of type double. It is equivalent to the value returned by Double.longBitsToDouble(0x7ff8000000000000L).”

and:

「float型のNot-a-Number(NaN)値を保持する定数。 これは、Float.intBitsToFloat(0x7fc00000)によって返される値と同等です。」

Javaの他の数値データ型には、このタイプの定数はありません。

3. NaNとの比較

Javaでメソッドを作成する際、入力が有効であり、予想される範囲内にあることを確認する必要があります。 ほとんどの場合、NaN値は有効な入力ではありません。 したがって、入力値がNaN値ではないことを確認し、これらの入力値を適切に処理する必要があります。

NaNは、フローティングタイプの値と比較することはできません。 これは、NaNを含むすべての比較操作でfalseを取得することを意味します(trueを取得する「!=」を除く)。

xNaN:である場合にのみ、「x != x”」に対してtrueを取得します。

System.out.println("NaN == 1 = " + (NAN == 1));
System.out.println("NaN > 1 = " + (NAN > 1));
System.out.println("NaN < 1 = " + (NAN < 1));
System.out.println("NaN != 1 = " + (NAN != 1));
System.out.println("NaN == NaN = " + (NAN == NAN));
System.out.println("NaN > NaN = " + (NAN > NAN));
System.out.println("NaN < NaN = " + (NAN < NAN));
System.out.println("NaN != NaN = " + (NAN != NAN));

上記のコードを実行した結果を見てみましょう。

NaN == 1 = false
NaN > 1 = false
NaN < 1 = false
NaN != 1 = true
NaN == NaN = false
NaN > NaN = false
NaN < NaN = false
NaN != NaN = true

したがって、we cannot check for NaN by comparing with NaN using “==” or “!= “.実際、floatまたはdoubleタイプで「==」または「!=」演算子を使用することはめったにありません。

代わりに、式「x ! = x」.を使用できます。この式はNAN.に対してのみtrueを返します。

メソッドFloat.isNaNおよびDouble.isNaNを使用して、これらの値をチェックすることもできます.これは、より読みやすく理解しやすいため、推奨されるアプローチです。

double x = 1;
System.out.println(x + " is NaN = " + (x != x));
System.out.println(x + " is NaN = " + (Double.isNaN(x)));

x = Double.NaN;
System.out.println(x + " is NaN = " + (x != x));
System.out.println(x + " is NaN = " + (Double.isNaN(x)));

このコードを実行すると、次の結果が得られます。

1.0 is NaN = false
1.0 is NaN = false
NaN is NaN = true
NaN is NaN = true

4. NaNを生成する操作

floatおよびdoubleタイプを含む操作を実行するときは、NaN値に注意する必要があります。

Some floating-point methods and operations produce NaN values instead of throwing an Exception.このような結果を明示的に処理する必要がある場合があります。

数値以外の値になる一般的なケースは、mathematically undefined numerical operationsです。

double ZERO = 0;
System.out.println("ZERO / ZERO = " + (ZERO / ZERO));
System.out.println("INFINITY - INFINITY = " +
  (Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY));
System.out.println("INFINITY * ZERO = " + (Double.POSITIVE_INFINITY * ZERO));

これらの例では、次の出力が得られます。

ZERO / ZERO = NaN
INFINITY - INFINITY = NaN
INFINITY * ZERO = NaN

実数の結果が得られない数値演算でも、NaN:が生成されます。

System.out.println("SQUARE ROOT OF -1 = " + Math.sqrt(-1));
System.out.println("LOG OF -1 = " +  Math.log(-1));

これらのステートメントの結果は次のとおりです。

SQUARE ROOT OF -1 = NaN
LOG OF -1 = NaN

オペランドとしてNaNを使用するすべての数値演算は、結果としてNaNを生成します。

System.out.println("2 + NaN = " +  (2 + Double.NaN));
System.out.println("2 - NaN = " +  (2 - Double.NaN));
System.out.println("2 * NaN = " +  (2 * Double.NaN));
System.out.println("2 / NaN = " +  (2 / Double.NaN));

そして、上記の結果は次のとおりです。

2 + NaN = NaN
2 - NaN = NaN
2 * NaN = NaN
2 / NaN = NaN

最後に、nulldoubleまたはfloatタイプ変数に割り当てることはできません。 代わりに、NaNをそのような変数に明示的に割り当てて、欠落している値または不明な値を示すことができます。

double maxValue = Double.NaN;

5. 結論

この記事では、NaNとそれに関連するさまざまな操作について説明しました。 また、Javaで浮動小数点計算を明示的に実行するときにNaNを処理する必要性についても説明しました。

完全なソースコードはover on GitHubにあります。