2012-04-03 11 views
32

kilka interesujących obserwacji w.r.t równa operatora na 0 i 0,0Równa operator dla zer (BigDecimal/Double) w Javie

  1. new Double(0.0).equals(0) zwraca false, natomiast new Double(0.0).equals(0.0) zwraca true.

  2. BigDecimal.ZERO.equals(BigDecimal.valueOf(0.0)) zwraca wartość false, a BigDecimal.ZERO.equals(BigDecimal.valueOf(0)) zwraca wartość true.

Wygląda na to, że porównywanie ciągów odbywa się w obu przypadkach. Czy ktokolwiek mógłby rzucić trochę światła na to.

Dzięki.

Odpowiedz

59

BigDecimal "equals" porównuje wartość i skalę. Jeśli chcesz tylko porównać wartości (0 == 0,0) należy użyć compareTo:

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

Zobacz javadoc.

Jeśli chodzi o podwójne porównanie, jak wyjaśniono innymi odpowiedziami, porównujesz Double z Integer w new Double(0.0).equals(0), który zwraca false, ponieważ obiekty mają różne typy. Dla porównania, code for the equals method in JDK 7 jest:

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

W twoim przypadku, (obj instanceof Double) jest fałszywe.

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

jako przekazywany argument jest liczbą całkowitą. i equels() w podwójną klasy sprawdza, czy argument jest od przykład dwukrotnie lub nie używając instancję operatora.

Metoda Podwójna równa się() równa się().

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

Argument zdałeś jest całkowitą, który nie jest instancją Podwójne, więc zwraca false.

5
  1. W 0 w pierwszym wyrazem jest interpretowane jako int, które mogą być autoboxed się z Integer, ale nie do Double. Więc typ tych dwóch jest inny, dlatego nie są równi. OTOH 0.0 to double, który jest autoboxed do Double, więc dwa operandy są uznawane za równe.

  2. BigDecimals zawierają również skalę (tj. Liczbę cyfr po prawej stronie kropki separatora dziesiętnego). BigDecimal.ZERO ma wartość "0", więc jego skala wynosi 0. Dlatego nie jest równa "0.0", której skala wynosi 1.
    Jeśli chcesz porównać wartości, użyj BigDecimal.compareTo:

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

nowy Podwójne (0,0) .equals (0) jest właściwie zapakowane, jak coś takiego:

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

Double.equals (...) nigdy nie zwróci wartości true, chyba że otrzyma inną podwójną instancję.

+0

@LukasEder Dzięki, zaktualizowany. – Adam

0
new Double(0.0).equals(0) 

Linia porównuje podwójną wartość 0 (co nie jest dokładne zero) z całkowitą 0.

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

BigDecimal porówna długość skali w operacji Wynik.

0

Ze względów wydajności BigDecimal, BigInteger buforuje małe wartości 0 do 15 w przypadku BigDecimal (bez frakcji)

BigDecimal.ZERO będzie nowych BigDecimal (BigInteger.ZERO, 0, 0, 1) & valueOf metoda zwykle pobiera z pamięci podręcznej od 0 do 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

Przekształcenie BigDecimal do double może spowodować utratę precyzji i niezerową, ale zbliżoną do zera BigDecimal przekształconą w Double może się równać 0. Powinieneś porównać używając metody 'compareTo' w BigDecimal –