Оператор равенства для нулей (BigDecimal / Double) в Java - PullRequest
33 голосов
/ 03 апреля 2012

Несколько интересных наблюдений относительно оператора равенства на 0 и 0.0

  1. new Double(0.0).equals(0) возвращает false, а new Double(0.0).equals(0.0) возвращает true.

  2. BigDecimal.ZERO.equals(BigDecimal.valueOf(0.0)) возвращает false, а BigDecimal.ZERO.equals(BigDecimal.valueOf(0)) возвращает true.

Похоже, что сравнение строк выполняется в обоих случаях.Кто-нибудь может пролить свет на это.

Спасибо.

Ответы [ 7 ]

63 голосов
/ 03 апреля 2012

BigDecimal 'equals' сравнивает значение и масштаб. Если вы хотите сравнить только значения (0 == 0,0), вам следует использовать compareTo:

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

См. Javadoc .

Что касается сравнения Double, как объясняется другими ответами, вы сравниваете Double с целым числом в new Double(0.0).equals(0), которое возвращает false, потому что объекты имеют разные типы. Для справки, код для метода равных в JDK 7 :

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

В вашем случае (obj instanceof Double) неверно.

5 голосов
/ 03 апреля 2012
  1. 0 в вашем первом выражении интерпретируется как int, который может быть автоматически помещен в Integer, но не в Double. Таким образом, тип двух отличается, следовательно, они не равны. OTOH 0.0 - это double, который автоматически помещается в Double, поэтому два операнда считаются равными.

  2. BigDecimals также содержат шкалу (то есть количество цифр справа от десятичной точки разделителя). BigDecimal.ZERO имеет значение "0", поэтому его масштаб равен 0. Следовательно, он не равен "0.0", масштаб которого равен 1.
    Если вы хотите сравнить значения, используйте BigDecimal.compareTo:

    BigDecimal.ZERO.compareTo(BigDecimal.valueOf(0.0)) == 0
    BigDecimal.ZERO.compareTo(BigDecimal.valueOf(0)) == 0
    
1 голос
/ 03 апреля 2012

new Double (0.0) .equals (0) на самом деле упакован примерно так:

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

Double.equals (...) никогда не вернет true, если не будет предоставлен другой экземпляр Double.

1 голос
/ 03 апреля 2012
new Double(0.0).equals(0); //false

в качестве аргумента, который вы передали, является целым числом. и класс equels () в Double проверяет, является ли аргумент od instance Double или не использует экземпляр оператора .

Метод Double ' равно () .

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

Переданный вами аргумент: integer , который не является экземпляром Double , поэтому возвращает false.

0 голосов
/ 07 августа 2012
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");
} 
0 голосов
/ 03 апреля 2012

Из соображений производительности BigDecimal, BigInteger кэширует небольшие значения от 0 до 15 в случае BigDecimal (без дробей)

BigDecimal.ZERO будет новым BigDecimal (BigInteger.ZERO, 0, 0, 1) и методом valueOfобычно забирает из кеша от 0 до 15:)

0 голосов
/ 03 апреля 2012
new Double(0.0).equals(0)

Эта строка сравнивает двойное значение 0 (которое не является точным нулем) с целым числом 0.

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

BigDecimal будет сравнивать длину шкалы в операции равенства.

...