JavaのNaN

1.概要

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

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

2. NaN とは何ですか?

  • NaN は通常、無効な演算の結果を示します。

  • 表現できない値にも NaN を使用します** -1の平方根はそのような場合の1つです。

https://en.wikipedia.org/wiki/IEEE 754[浮動小数点演算のためのIEEE規格(IEEE 754)]は NaN 値を定義します。 ** Javaでは、浮動小数点型 float double__がこの標準を実装しています。

Javaでは、 float 型と double 型の両方の NaN 定数をhttps://docs.oracle.com/javase/8/docs/api/java/lang/Float.html#NaN[ Float .NaN]およびhttps://docsとして定義しています。 oracle.com/javase/8/docs/api/java/lang/Double.html#NaN[ Double.NaN ]:

double型の非数(NaN)値を保持する定数。 Double.longBitsToDouble(0x7ff8000000000000L)が返す値と同じです。

そして:

__ float型の非数(NaN)値を保持する定数。これは、Float.intBitsToFloat(0x7fc00000)によって返される値と同じです。

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

3. NaN との比較

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

NaN は、どの浮動小数点値とも比較できません。これは、 NaN を含むすべての比較演算に対して false が得られることを意味します(ただし、 true を求める「!=」を除く)。

x NaNの場合に限り、“ 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

したがって、** = =や!=を使って NaN と比較して NaN をチェックすることはできません。

代わりに、式“ __ x! = x” . を使用できます。この式は NAN.__に対してのみ真を返します。

メソッド 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 の値を知っておく必要があります。

  • 一部の浮動小数点メソッドおよび演算では、 Exceptionをスローする代わりに NaN__値が生成されます。

非数値になる一般的なケースは、 数学的に未定義の数値演算 です。

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

最後に、 null double または float 型の変数に代入することはできません。

代わりに、欠損値または未知の値を示すために、そのような変数に NaN を明示的に割り当てることができます。

double maxValue = Double.NaN;

5.まとめ

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

完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/java-numbers[GitHubについて]で見つけることができます。