2012-04-03 14 views
32

Alcune osservazioni interessanti w.r.t equivale operatore 0 e 0.0Uguale operatore zeri (BigDecimal/doppia) in Java

  1. new Double(0.0).equals(0) restituisce false, mentre new Double(0.0).equals(0.0) restituisce vero.

  2. BigDecimal.ZERO.equals(BigDecimal.valueOf(0.0)) restituisce false, mentre BigDecimal.ZERO.equals(BigDecimal.valueOf(0)) restituisce true.

si presenta come il confronto di stringhe è stato fatto in entrambi i casi. Qualcuno potrebbe far luce su questo.

Grazie.

risposta

59

BigDecimal "uguale" confronta il valore e la scala. Se si desidera solo per confrontare i valori (0 == 0.0) si dovrebbe usare compareTo:

BigDecimal.ZERO.compareTo(BigDecimal.valueOf(0.0)) == 0 //true 
BigDecimal.ZERO.compareTo(BigDecimal.valueOf(0)) == 0 //true 

Vedere le javadoc.

Per quanto riguarda il doppio confronto, come spiegato da altre risposte, si sta confrontando una doppia con un intero new Double(0.0).equals(0), che restituisce false perché gli oggetti hanno tipi differenti. Per riferimento, il code for the equals method in JDK 7 è:

public boolean equals(Object obj) { 
    return (obj instanceof Double) 
      && (doubleToLongBits(((Double)obj).value) == 
        doubleToLongBits(value)); 
} 

Nel tuo caso, (obj instanceof Double) è falso.

1
new Double(0.0).equals(0); //false 

come argomento che è passato è intero. e le equels() in doppie controlli di classe se l'argomento è da esempio Doppia o non utilizzo di istanza di dell'operatore.

Il doppio 's uguale() metodo.

if (!(argument instanceof Double)) 
    return false; 

L'argomento è stato passato è intero, che non è un'istanza di doppio, quindi restituisce false.

5
  1. Il 0 nella prima espressione viene interpretata come un int, che può essere in un autoboxed Integer, ma non a un Double. Quindi il tipo dei due è diverso, quindi non sono uguali. OTOH 0.0 è un double, che è autoboxed in un Double, quindi i due operandi sono considerati uguali.

  2. I BigDecimali contengono anche una scala (ovvero il numero di cifre a destra del punto del separatore decimale). BigDecimal.ZERO ha il valore di "0", quindi la sua scala è 0. Quindi non è uguale a "0.0", la cui scala è 1.
    Se si desidera confrontare i valori, utilizzare BigDecimal.compareTo:

    BigDecimal.ZERO.compareTo(BigDecimal.valueOf(0.0)) == 0 
    BigDecimal.ZERO.compareTo(BigDecimal.valueOf(0)) == 0 
    
0

nuovo doppio (0,0) .equals (0) è in realtà inscatolati come qualcosa di simile a questo:

new Double(0.0).equals(Integer.valueOf(0)) 

Double.equals (...) non restituirà mai true a meno che non venga fornita un'altra istanza Double.

+0

@LukasEder Grazie, aggiornato. – Adam

0
new Double(0.0).equals(0) 

Questa riga confronta un valore doppio di 0 (che non è esatta zero) con numero intero da 0.

BigDecimal.ZERO.equals(BigDecimal.valueOf(0.0)) 

BigDecimal confronterà la lunghezza della scala nell'operazione pari.

0

Per considerazioni di prestazioni BigDecimal, BigInteger memorizza nella cache piccoli valori 0 a 15 in caso di BigDecimal (senza decimali)

BigDecimal.ZERO sarà nuovo BigDecimal (BigInteger.ZERO, 0, 0, 1) & valueOf metodo in genere preleva dalla cache per 0 a 15 :)

0
please try doublevalue instead of compareto if you feel is not as beautiful and readable as or simply need an alternative like below: 

BigDecimal a = new BigDecimal("0.00"); 
BigDecimal b = new BigDecimal("0.0"); 
BigDecimal c = new BigDecimal("0"); 

if(a.doubleValue()==BigDecimal.ZERO.doubleValue()) { 
System.out.println("a equals"); 
} 

if(b.doubleValue()==BigDecimal.ZERO.doubleValue()) { 
System.out.println("b equals"); 
} 

if(c.doubleValue()==BigDecimal.ZERO.doubleValue()) { 
System.out.println("c equals"); 
} 
+1

La trasformazione di un BigDecimal in un double può comportare una perdita di precisione e un valore non zero ma vicino a zero BigDecimal trasformato in Double potrebbe diventare 0. È necessario confrontare utilizzando il metodo 'compareTo' in BigDecimal –