Ich habe gerade OCPJP-Fragen studiert und diesen seltsamen Code gefunden:
public static void main(String a[]) {
System.out.println(Double.NaN==Double.NaN);
System.out.println(Double.NaN!=Double.NaN);
}
Als ich den Code ausführte, bekam ich:
false
true
Wie ist die Ausgabe, false
wenn wir zwei Dinge vergleichen, die gleich aussehen? Was heißt NaN
das
In [1]: NaN==NaN Out[1]: False
Double.NaN==Double.NaN
sollte tatsächlich true zurückgeben, wenn erDouble.NaN
vom Typ wärejava.lang.Double
. Sein Typ ist jedoch das Grundelementdouble
, und es gelten die Operatorregelndouble
(die diese Ungleichung für die Konformität mit IEEE 754 erfordern, wie in den Antworten erläutert).Antworten:
NaN bedeutet "keine Zahl".
In der dritten Ausgabe der Java Language Specification (JLS) heißt es :
quelle
false
. Dieser Standard unterscheidet sich von Java darin, dass IEEE dies verlangt(NAN != NAN) == false
.NaN ist per Definition nicht gleich einer Zahl einschließlich NaN. Dies ist Teil des IEEE 754-Standards und wird von der CPU / FPU implementiert. Die JVM muss keine Logik zur Unterstützung hinzufügen.
http://en.wikipedia.org/wiki/NaN
Java behandelt alles NaN als leises NaN.
quelle
Warum diese Logik?
NaN
bedeutetNot a Number
. Was ist keine Nummer? Etwas. Sie können alles auf der einen Seite und alles auf der anderen Seite haben, also garantiert nichts, dass beide gleich sind.NaN
wird berechnet mitDouble.longBitsToDouble(0x7ff8000000000000L)
und wie Sie in der Dokumentation von sehen könnenlongBitsToDouble
:Wird auch
NaN
innerhalb der API logisch behandelt.Dokumentation
By the way,
NaN
wird als Ihr Codebeispiel getestet:Lösung
Was Sie tun können, ist
compare
/compareTo
:Oder
equals
:quelle
NaN != NaN
in dem Falschheit Programme komplizierter machen würdeNaN != NaN
als Wahrhaftigkeit? Ich weiß, dass IEEE die Entscheidung vor langer Zeit getroffen hat, aber aus praktischer Sicht habe ich noch nie Fälle gesehen, in denen dies nützlich ist. Wenn eine Operation ausgeführt werden soll, bis aufeinanderfolgende Iterationen das gleiche Ergebnis liefern, würden zwei aufeinanderfolgende Iterationen, die NaN ergeben, "natürlich" als Ausgangsbedingung erkannt, wenn dieses Verhalten nicht vorhanden wäre.f(f(f...f(x)))
, und many=f[n](x)
für einige einen
solche findet, von der das Ergebnis vonf(y)
nicht zu unterscheiden isty
, danny
ist man vom Ergebnis eines tiefer verschachtelten nicht zu unterscheidenf(f(f(...f(y)))
. Selbst wenn manNaN==NaN
falsch sein wollte , wäre es weniger "überraschend" ,Nan!=Nan
auch falsch zu sein,x!=x
als für einige x wahr zu sein.Double.NaN
ist nichtDouble
, aberdouble
die Frage bezieht sich also auf das Verhalten vondouble
. Obwohl es Funktionen gibt, die auf eine Äquivalenzbeziehung mitdouble
Werten testen können, ist die einzige überzeugende Antwort, die ich für "warum" (was Teil der ursprünglichen Frage ist) kenne, "weil einige Leute am IEEE nicht dachten, dass Gleichheitstests dies tun sollten eine Äquivalenzbeziehung definieren ". Übrigens, gibt es eine prägnante idiomatische Methode zum Testenx
undy
zur Äquivalenz, bei der nur primitive Operatoren verwendet werden? Alle Formulierungen, die ich kenne, sind ziemlich klobig.Es ist möglicherweise keine direkte Antwort auf die Frage. Wenn Sie jedoch überprüfen möchten, ob etwas gleich ist,
Double.NaN
sollten Sie Folgendes verwenden:Dies wird zurückkehren
true
quelle
Der Javadoc für Double.NaN sagt alles:
Interessanterweise
Double
definiert die Quelle fürNaN
:Das von Ihnen beschriebene spezielle Verhalten ist fest mit der JVM verbunden.
quelle
gemäß IEEE-Standard für Gleitkomma-Arithmetik für doppelte Präzisionszahlen,
wo,
Was bedeutet,
Wenn alle
E
Bits 1 sind und ein Bit ungleich Null vorhanden ist, lautetF
die ZahlNaN
.daher sind unter anderem alle folgenden Zahlen
NaN
:Insbesondere können Sie nicht testen
um zu überprüfen, ob ein bestimmtes Ergebnis gleich ist
Double.NaN
, da alle Werte "keine Zahl" als unterschiedlich betrachtet werden. Sie können jedoch die folgendeDouble.isNaN
Methode verwenden:quelle
NaN ist ein spezieller Wert, der "keine Zahl" bezeichnet. Es ist das Ergebnis bestimmter ungültiger arithmetischer Operationen, wie z. B.
sqrt(-1)
und hat die (manchmal ärgerliche) Eigenschaft, dassNaN != NaN
.quelle
Keine Zahl repräsentiert das Ergebnis von Operationen, deren Ergebnis mit einer Zahl nicht darstellbar ist. Die bekannteste Operation ist 0/0, deren Ergebnis nicht bekannt ist.
Aus diesem Grund ist NaN gleich nichts (einschließlich anderer Nicht-Zahlen-Werte). Weitere Informationen finden Sie auf der Wikipedia-Seite: http://en.wikipedia.org/wiki/NaN
quelle
0/0
.0/0
ist immer NaN, aber NaN kann das Ergebnis anderer Operationen sein - wie zum Beispiel2+NaN
:an operation that has no mathematically definite result produces NaN
gemäß der Antwort von @AdrianMitevNach diesem Link hat es verschiedene Situationen und schwer zu merken. So erinnere ich mich und unterscheide sie.
NaN
bedeutet zum Beispiel "mathematisch undefiniert": "Das Ergebnis von 0 geteilt durch 0 ist undefiniert" und weil es undefiniert ist, ist "Vergleich in Bezug auf undefiniert natürlich undefiniert". Außerdem funktioniert es eher wie mathematische Prämissen. Andererseits ist sowohl das positive als auch das negative Unendliche vordefiniert und endgültig, zum Beispiel "positiv oder negativ unendlich groß ist mathematisch gut definiert".quelle