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について]で見つけることができます。