Von apidoc, Float.compare
:
Vergleicht die beiden angegebenen Float-Werte. Das Vorzeichen des ganzzahligen Wert zurückgegeben wird, ist die gleiche wie die der ganzen Zahl, die durch den Aufruf zurückgegeben werden würde:
neue Float (f1) .compareTo (new Float (f2))
Float.compareTo
:
Vergleicht zwei Float-Objekte numerisch. Es gibt zwei Möglichkeiten, in denen nach dieser Methode durchgeführt Vergleiche aus, die durch die Java-Sprache numerischen Vergleichsoperatoren durchgeführt unterscheiden (<, < =, ==,> =>), wenn auf primitive float-Werte:
- Float. NaN wird bei dieser Methode als gleich groß und größer als alle anderen Float-Werte (einschließlich Float.POSITIVE_INFINITY) betrachtet.
- 0.0f wird von dieser Methode als größer als -0.0f betrachtet.
Dies stellt sicher, dass die natürliche Ordnung der Float-Objekte durch dieses Verfahren verhängten mit equals konsistent ist.
Betrachten Sie den folgenden Code ein:
System.out.println(-0.0f == 0.0f); //true
System.out.println(Float.compare(-0.0f, 0.0f) == 0 ? true : false); //false
System.out.println(Float.NaN == Float.NaN);//false
System.out.println(Float.compare(Float.NaN, Float.NaN) == 0 ? true : false); //true
System.out.println(-0.0d == 0.0d); //true
System.out.println(Double.compare(-0.0d, 0.0d) == 0 ? true : false);//false
System.out.println(Double.NaN == Double.NaN);//false
System.out.println(Double.compare(Double.NaN, Double.NaN) == 0 ? true : false);//true
Der Ausgang ist nicht korrekt, da etwas, das keine Zahl ist, ist einfach nicht eine Zahl ist, und soll gleich von Nummer Vergleichspunkt behandelt werden, von Aussicht. Es ist auch klar, dass 0=-0
.
Mal sehen, was Float.compare
tut:
public static int compare(float f1, float f2) {
if (f1 < f2)
return -1; // Neither val is NaN, thisVal is smaller
if (f1 > f2)
return 1; // Neither val is NaN, thisVal is larger
int thisBits = Float.floatToIntBits(f1);
int anotherBits = Float.floatToIntBits(f2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
Float.floatToIntBits
:
Gibt eine Darstellung des angegebenen Gleitkommawert nach dem IEEE 754 Floating-Point "single-Format" Bit-Layout . Bit 31 (das Bit, das von der Maske 0x80000000 ausgewählt wird) stellt das Vorzeichen der Fließkommazahl dar. Die Bits 30-23 (die Bits, die von der Maske 0x7f800000 ausgewählt werden) repräsentieren den Exponenten. Die Bits 22-0 (die Bits, die durch die Maske 0x007fffff ausgewählt werden) repräsentieren die Mantisse der Gleitkommazahl.
Wenn das Argument positiv unendlich ist, lautet das Ergebnis 0x7f800000.
Wenn das Argument negativ unendlich ist, lautet das Ergebnis 0xff800000.
Wenn das Argument NaN ist, ist das Ergebnis 0x7fc00000. In allen Fällen ist das Ergebnis eine ganze Zahl, die, wenn sie der intBitsToFloat (int) -Methode übergeben wird, einen Gleitkommawert erzeugt, der dem Argument von floatToIntBits entspricht (, außer dass alle NaN-Werte auf einen einzigen Wert reduziert sind) "kanonischer" NaN-Wert).
Von JLS 15.20.1. Numerical Comparison Operators <, <=, >, and >=
Das Ergebnis einer Gleitkomma-Vergleich, wie sie in der Spezifikation der Norm IEEE 754 bestimmt, ist:
Falls einer der Operanden NaN ist, dann Das Ergebnis ist falsch.
Alle anderen Werte als NaN sind geordnet, wobei die negative Unendlichkeit kleiner als alle endlichen Werte und die positive Unendlichkeit größer als alle endlichen Werte ist.
Positive Null und negative Null werden als gleich betrachtet. Zum Beispiel ist -0.0 < 0.0 falsch, aber -0.0 < = 0.0 ist wahr.
Beachten Sie jedoch, dass die Methoden Math.min und Math.max den negativen Nullwert als streng kleiner als den positiven Nullwert behandeln.
Für strenge Vergleiche wo Operanden sind positive Null und negative Null das Ergebnis falsch sein wird.
Von JLS 15.21.1. Numerical Equality Operators == and !=:
Das Ergebnis eines Gleitkomma-Vergleich, wie sie in der Spezifikation der Norm IEEE 754 bestimmt, ist:
Gleitkommazahl Gleichheit Prüfung wird in Übereinstimmung mit der durchgeführt Regeln der IEEE-Norm 754:
Wenn einer der Operanden NaN, dann ist das Ergebnis von == ist falsch, aber das Ergebnis ist = ist wahr!. In der Tat ist der Test x! = X genau dann wahr, wenn der Wert von x NaN ist. Die Methoden Float.isNaN und Double.isNaN können auch verwendet werden, um zu testen, ob ein Wert NaN ist.
Positive Null und negative Null werden als gleich betrachtet. Zum Beispiel ist -0.0 == 0.0 wahr.
Andernfalls werden zwei unterschiedliche Gleitkommawerte von den Gleichheitsoperatoren als ungleich betrachtet. Insbesondere gibt es einen Wert für die positive Unendlichkeit und einen Wert für die negative Unendlichkeit. Jeder vergleicht sich nur mit sich selbst, und jeder vergleicht ungleich mit allen anderen Werten.
Für Gleichheitsvergleiche, wo beide Operanden NaN wird das Ergebnis falsch sein.
Da total ordering (=
, <
, >
,<=
, >=
) von vielen wichtigen Algorithmen verwendet wird (siehe all the classes that implement the Comparable interface), ist es besser, die Vergleichsmethode zu verwenden, da dies zu einem konsistenteren Verhalten führt.
Die Konsequenz der total ordering in the context of the IEEE-754 standard ist die Differenz zwischen dem positiven und negativen Nullpunkt. Wenn Sie beispielsweise den Gleichheitsoperator anstelle der Vergleichsmethode verwenden und eine Sammlung von Werten haben und Ihre Codelogik einige Entscheidungen basierend auf der Reihenfolge der Elemente trifft, erhalten Sie irgendwie einen Überschuss an NaN-Werten Sie werden alle als unterschiedliche Werte anstatt als dieselben Werte behandelt.
Dies kann wahrscheinlich Fehler im Verhalten des Programms proportional zur Menge/Rate der NaN-Werte erzeugen. Und wenn Sie viele positive und negative Nullen haben, ist das nur ein Paar, das Ihre Logik mit Fehlern beeinflusst.
Float uses IEEE-754 32-Bit-Format und Double uses IEEE-754 64-Bit-Format.
Ist ein NaN gleich einem anderen NaN? Ist es größer als, kleiner oder gleich einer anderen Zahl? Ist -0.0f gleich 0.0f? –
http://Stackoverflow.com/a/9341669/1276341 – MrLore
Es hängt davon ab, was Sie tun möchten. IIRC (halte mich nicht an) NaN == NaN ist falsch, z. Aber die offizielle Spezifikation von 'compare' gibt dir nicht viele Informationen darüber, wie die" Oddball "-Fälle gehandhabt werden. Wichtiger ist, sich daran zu erinnern, nie für "gleich" zu vergleichen, außer in speziellen Fällen, in denen Sie wissen, was Sie tun. –