怒Mは思いつきでモノを言う

やったことメモなどなど

NaNってなんなんだ?

先日、こんなツイートを見かけました。

NaNってなんだっけ?
どっかで見た記憶があるけどなんだっけなー。

NaN - Wikipedia

IEEE 754 - Wikipedia

なるほど。非数。
ついでにIEEE754についてもWikiレベルで確認。

解釈は納得。
NaNはJavaでも定義されている様です。
JavaScriptと同様に==ではfalseとなるのかが気になります。また、==では常にfalseとなる理由が気になるので少し調べてみました。

NaNとか意識したことないから、とりあえず比較してみました。

Double nan1 = Double.NaN;
Double nan2 = Double.NaN;
        
if(nan1 == nan2) System.out.println("nan1 == nan2 => true");
if(nan1.equals(nan2)) System.out.println("nan1.equals(nan2) => true");
if(nan1.doubleValue() == nan2.doubleValue()) 
    System.out.println("nan1.doubleValue() == nan2.doubleValue() => true");
        
System.out.println("Double.doubleToLongBits(nan1) => " + Double.doubleToLongBits(nan1));
System.out.println("Double.doubleToLongBits(nan2) => " + Double.doubleToLongBits(nan2));
        
System.out.println("nan1.hashCode() => " + nan1.hashCode());
System.out.println("nan2.hashCode() => " + nan2.hashCode());
nan1.equals(nan2) => true
Double.doubleToLongBits(nan1) => 9221120237041090560
Double.doubleToLongBits(nan2) => 9221120237041090560
nan1.hashCode() => 2146959360
nan2.hashCode() => 2146959360

==での比較はfalseになるけど、equals()を使うとtrueとなる、と。
なんなんでしょう、まったく。意味がわからないです。
equals()の結果がtrueとなるのは仕様のようです。

Double (Java Platform SE 8)

Javaの言語規格で==について調べてみました。

If either operand is NaN, then the result of == is false but the result of != is true.

Indeed, the test x!=x is true if and only if the value of x is NaN.

The methods Float.isNaN and Double.isNaN may also be used to test whether a value is NaN.

引用元:http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.21.1

NaNの==での比較結果は無条件でfalseとなると解釈しました。

これはJavaScriptでも同様なようですね。

developer.mozilla.org

比較演算子 (JavaScript)

MATLABでも同じように記載されています。

jp.mathworks.com


NaNであるかのチェックは大体は、
isNaN()を使いましょうというのが常識なようです。
NaNがなんなのか知ることができて、スッキリしました。NaNの扱いについては言語が変わっても統一されているようですね。(当然か)