Da apidoc, Float.compare
:
confronta i due valori float specificati. Il segno del valore intero restituito è lo stesso di quello del numero intero che verrebbe restituito dalla chiamata:
nuovo Float (f1) .compareTo (nuovo Float (f2))
Float.compareTo
:
Confronta numericamente due oggetti Float. Ci sono due modi in cui confronti eseguiti con tale metodo differiscono da quelle eseguite dagli operatori di confronto numerico linguaggio Java (<, < =, ==,> =>) quando applicato ai valori float primitive:
- galleggiante. NaN è considerato da questo metodo uguale a se stesso e maggiore di tutti gli altri valori float (incluso Float.POSITIVE_INFINITY).
- 0.0f è considerato da questo metodo maggiore di -0.0f.
Ciò garantisce che l'ordine naturale degli oggetti Float imposti da questo metodo sia coerente con gli uguali.
Si consideri il seguente codice:
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
L'output non è corretto, in quanto qualcosa che non è un numero, non è semplicemente un numero, e deve essere trattato come uguale dal punto di confronto il numero di vista. È anche chiaro che 0=-0
.
Vediamo cosa Float.compare
fa:
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
:
restituisce una rappresentazione del valore a virgola mobile specificato in base a virgola mobile IEEE 754 "formato single" la layout bit . Il bit 31 (il bit selezionato dalla maschera 0x80000000) rappresenta il segno del numero a virgola mobile. I bit 30-23 (i bit selezionati dalla maschera 0x7f800000) rappresentano l'esponente. I bit 22-0 (i bit selezionati dalla maschera 0x007fffff) rappresentano il significato e (talvolta chiamato la mantissa) del numero a virgola mobile.
Se l'argomento è infinito positivo, il risultato è 0x7f800000.
Se l'argomento è infinito negativo, il risultato è 0xff800000.
Se l'argomento è NaN, il risultato è 0x7fc00000.
In tutti i casi, il risultato è un intero che, quando somministrato al metodo intBitsToFloat (int), produrrà un valore di virgola mobile stesso come argomento di floatToIntBits (eccetto tutti valori NaN sono collassati per un singolo "canonico" valore NaN).
Da JLS 15.20.1. Numerical Comparison Operators <, <=, >, and >=
Il risultato di un confronto in virgola mobile, come determinato dalle specifiche dello standard IEEE 754, è:
Se uno degli operandi è NaN, allora il risultato è falso
Tutti i valori diversi da NaN sono ordinati, con infinito negativo minore di tutti i valori finiti e infinito positivo maggiore di tutti i valori finiti.
Lo zero positivo e lo zero negativo sono considerati uguali. Ad esempio, -0,0 < 0,0 è falso, ma -0,0 < = 0,0 è vero.
Si noti, tuttavia, che i metodi Math.min e Math.max trattano lo zero negativo come strettamente inferiore allo zero positivo.
Per i confronti severe dove operandi sono zero positivo e zero negativo il risultato sarà sbagliato.
Da JLS 15.21.1. Numerical Equality Operators == and !=:
Il risultato di un confronto in virgola mobile, come determinato dalle specifiche dello standard IEEE 754, è: test di uguaglianza
virgola mobile viene eseguita secondo la regole dello standard IEEE 754:
Se uno degli operandi è NaN, allora il risultato del == è falso, ma il risultato di = è vero!. In effetti, il test x! = X è vero se e solo se il valore di x è NaN. I metodi Float.isNaN e Double.isNaN possono anche essere utilizzati per verificare se un valore è NaN.
Lo zero positivo e lo zero negativo sono considerati uguali. Ad esempio, -0.0 == 0.0 è vero.
In caso contrario, due valori distinti a virgola mobile vengono considerati non uguali dagli operatori di uguaglianza. In particolare, esiste un valore che rappresenta l'infinito positivo e un valore che rappresenta l'infinito negativo; ognuno confronta uguale solo a se stesso, e ciascuno confronta ineguale con tutti gli altri valori.
Per i confronti di uguaglianza in cui entrambi gli operandi sono NaN il risultato sarà sbagliato.
Poiché il total ordering (=
, <
, >
,<=
, >=
) è utilizzato da molti algoritmi importanti (vedere all the classes that implement the Comparable interface) è preferibile utilizzare il metodo di confronto in quanto produce un comportamento più coerente.
La conseguenza dello total ordering in the context of the IEEE-754 standard è la differenza tra lo zero positivo e negativo.
Ad esempio, se si utilizza l'operatore di uguaglianza anziché il metodo di confronto e si dispone di una raccolta di valori e la logica del codice prende alcune decisioni in base all'ordinamento degli elementi e in qualche modo si inizia a ottenere un surplus di valori NaN saranno tutti trattati come valori diversi invece degli stessi valori.
Ciò potrebbe produrre un errore nel comportamento del programma proporzionale alla quantità/velocità dei valori NaN. E se hai molti zeri positivi e negativi, è solo una coppia che incide sulla tua logica con errori.
Float uses Formato IEEE-754 a 32 bit e doppio uses Formato 64 bit IEEE-754.
È un NaN uguale a qualsiasi altro NaN? È maggiore di, inferiore o uguale a qualsiasi altro numero? -0.0f è uguale a 0.0f? –
http://stackoverflow.com/a/9341669/1276341 – MrLore
Dipende da cosa vuoi fare. IIRC (non trattenermi a questo) 'NaN == NaN' è falso, es. Ma le specifiche ufficiali di 'compare' non ti danno molte informazioni su come vengono gestiti i casi" oddball ". Più importante è ricordare di non confrontare mai per "uguale", tranne nei casi speciali in cui sai cosa stai facendo. –