2012-10-12 9 views
10

Citato da Effective Java - Seconda edizione di Joshua BlochIn che modo gli operatori relazionali non rispettano il contratto compareTo con i valori in virgola mobile?

Per i campi in virgola mobile, utilizzare Double.compare o Float.compare al posto degli operatori relazionali, che non obbediscono il contratto generale per compare: quando applicato a valori in virgola mobile.

Non spiega perché questo sia il caso.

Quindi, la mia domanda è:

In che modo fanno operatori relazionali non riescono a rispettare il contratto generale per compareTo quando viene utilizzato con valori in virgola mobile?

+2

Correlato: http://stackoverflow.com/a/3668105/396458 – NullUserException

+0

Questi valori consentono valori di NaN, (non di numero). –

risposta

6

Dal javadoc:

public int compareTo(Double anotherDouble) 

Confronta due oggetti doppie numericamente. Esistono due modi in cui i confronti eseguiti da questo metodo differiscono da quelli eseguiti dagli operatori di confronto numerico del linguaggio Java (<, < =, ==,> =,>) quando applicati a doppi valori primitivi: Double.NaN è considerato da questo metodo è uguale a se stesso e maggiore di tutti gli altri valori double (incluso Double.POSITIVE_INFINITY). 0.0d è considerato da questo metodo superiore a -0,0d. Ciò garantisce che l'ordinamento naturale degli oggetti Double imposti da questo metodo sia coerente con gli uguali.

+0

Grazie per il buon riferimento :) –

3

da Java doc Double#compareTo

Confronta due oggetti doppie numericamente. Ci sono due modi in cui comparazioni eseguite con questo metodo rispetto a quelli effettuati dagli operatori di confronto numerico linguaggio Java (<, < =, ==,> =>) quando applicato ai primitivi valori doppi:

  • Double.NaN è considerato da questo metodo uguale a se stesso e maggiore di tutti gli altri valori double (incluso Double.POSITIVE_INFINITY).

  • 0.0d è considerato da questo metodo maggiore di -0,0 d.

Questo assicura che Double.compareTo (Object) (che inoltra il suo comportamento a questo metodo) obbedisce al contratto generale per Comparable.compareTo, e che l'ordine naturale su Doubles è coerente con eguali.

double d1 =Double.NaN; 
    double d2 = Double.NaN; 

    System.out.println(Double.valueOf(d1).equals(d2)); ---> true 
    System.out.println(Double.valueOf(d1).compareTo(d2)); ---> 0 
    System.out.println(d1 == d2);       --->false 
+0

Ma, in particolare, non è coerente con gli operatori relazionali. –

+0

@LouisWasserman Sì. Aggiunto anche questo. –