Как проверить, если переменная BigDecimal == 0 в java?

У меня есть следующий код на Java;

BigDecimal price; // assigned elsewhere

if (price.compareTo(new BigDecimal("0.00")) == 0) {
    return true;
}

Как лучше всего написать условие if?


person JoJo    schedule 08.06.2012    source источник
comment
Во многих ответах предлагается использовать метод BigDecimal .equals (). Но этот метод принимает во внимание масштаб, поэтому не эквивалентен использованию compareTo ().   -  person GriffeyDog    schedule 08.06.2012


Ответы (11)


Используйте _1 _ вместо equals():

if (price.compareTo(BigDecimal.ZERO) == 0) // see below

Сравнение с константой BigDecimal _ 5_ позволяет избежать создания new BigDecimal(0) при каждом выполнении.

К вашему сведению, BigDecimal также имеет константы BigDecimal.ONE и BigDecimal.TEN для вашего удобства.


Примечание!

Причина, по которой вы не можете использовать _ 10_ заключается в том, что учитывается масштаб:

new BigDecimal("0").equals(BigDecimal.ZERO) // true
new BigDecimal("0.00").equals(BigDecimal.ZERO) // false!

поэтому он не подходит для чисто числового сравнения. Однако BigDecimal.compareTo() не учитывает масштаб при сравнении:

new BigDecimal("0").compareTo(BigDecimal.ZERO) == 0 // true
new BigDecimal("0.00").compareTo(BigDecimal.ZERO) == 0 // true
person Bohemian♦    schedule 08.06.2012
comment
BigDecimal.ZERO.compareTo (цена) == 0 - person Jackkobec; 27.01.2020
comment
Есть ли какая-то конкретная причина для этой реализации BigDecimal - new BigDecimal (0.00) .equals (BigDecimal.ZERO) // false !? Почему 0,00 не уменьшается до 0 с помощью шкалы 0? - person Pavel; 03.12.2020
comment
@Pavel - это все в документация. - person Bohemian♦; 03.12.2020
comment
странный! price == BigDecimal.valueOf (0.00d) неверно, когда цена равна нулю! - person Mehrnoosh; 20.05.2021
comment
@Mehrnoosh этого никогда не будет, потому что в Java == сравнивает идентичность объекта - то есть, если это один и тот же объект, а не если две стороны имеют равное значение. В Java всегда используйте .equals() для сравнения. - person Bohemian♦; 20.05.2021

Кроме того, signum () может использоваться:

if (price.signum() == 0) {
    return true;
}
person kman    schedule 30.08.2012
comment
Возможно, это быстрее, но compareTo (BigDecimal.ZERO) более читабелен. - person ElYeante; 06.03.2014
comment
@ElYeante, вы всегда можете обернуть это методом, который имеет более читаемое имя или даже описывает часть вашей бизнес-логики, связанную с таким сравнением - person WeGa; 07.04.2016
comment
К сожалению, signum () не является нулевым безопасным, тогда как compareTo - при сравнении типа BigDecimal.ZERO.compareTo (), поэтому обратите внимание на это - person WeGa; 18.10.2016
comment
@WeGa Это неправда: BigDecimal.ZERO.compareTo(null) выкинет NPE - person ACV; 06.04.2017
comment
@ACV, спасибо за бдительность. Посмотрев на исходный код, compareTo () действительно ожидает только ненулевой аргумент. - person WeGa; 10.04.2017

Есть константа, по которой вы можете проверить:

someBigDecimal.compareTo(BigDecimal.ZERO) == 0
person pablochan    schedule 08.06.2012
comment
Запрошено разрешение на кражу вашей терминологии состояния Йоды. - person SimplyPanda; 08.06.2012
comment
Это фантастика. - person SimplyPanda; 08.06.2012
comment
Поведение Java BigDecimal для equals и compareTo не такое, как вы думаете. документы .oracle.com / javase / 1.5.0 / docs / api / java / math /. - person nhahtdh; 31.08.2012
comment
Компонент compareTo BigDecimal по-прежнему вызовет исключение, если вы передадите значение null. - person John Jiang; 07.02.2013

В качестве альтернативы, я думаю, стоит упомянуть, что поведение методов equals и compareTo в классе BigDecimal не согласуются друг с другом.

В основном это означает, что:

BigDecimal someValue = new BigDecimal("0.00");
System.out.println(someValue.compareTo(BigDecimal.ZERO) == 0); // true
System.out.println(someValue.equals(BigDecimal.ZERO)); // false

Следовательно, вы должны быть очень осторожны с масштабом в вашей переменной someValue, иначе вы получите неожиданный результат.

person Edwin Dalorzo    schedule 08.06.2012

Обычно я использую следующее:

if (selectPrice.compareTo(BigDecimal.ZERO) == 0) { ... }
person gpol    schedule 08.06.2012

Вы хотели бы использовать equals(), поскольку они являются объектами, и использовать встроенный ZERO экземпляр:

if (selectPrice.equals(BigDecimal.ZERO))

Обратите внимание, что .equals() принимает во внимание масштаб, поэтому, если selectPrice не совпадает с масштабом (0), что и .ZERO, тогда это вернет false.

Чтобы как бы убрать масштаб из уравнения:

if (selectPrice.compareTo(BigDecimal.ZERO) == 0)

Я должен отметить, что для определенных математических ситуаций 0.00 != 0, поэтому я предполагаю, что .equals() принимает во внимание масштаб. 0.00 дает точность до сотых долей, тогда как 0 не так точна. В зависимости от ситуации вы можете придерживаться .equals().

person NominSim    schedule 08.06.2012
comment
Поведение Java BigDecimal для equals и compareTo не такое, как вы думаете. документы .oracle.com / javase / 1.5.0 / docs / api / java / math /. - person nhahtdh; 31.08.2012
comment
Хотите объяснить, что вы имеете в виду, вместо того, чтобы ссылаться на документы? То, что я предложил, должно работать на OP. - person NominSim; 31.08.2012
comment
Ответ Эдвина Далорцо на самом деле довольно хорошо это объясняет. equals принимает во внимание масштаб, а это не то, что мы здесь хотим. - person nhahtdh; 31.08.2012
comment
@nhahtdh Спасибо за информацию, хотя бывают ситуации, когда equals следует использовать вместо compareTo(). ОП не указывает, какой тип математики он использует, так что вы правы, лучше предоставить ему оба варианта. - person NominSim; 31.08.2012

GriffeyDog определенно прав:

Код:

BigDecimal myBigDecimal = new BigDecimal("00000000.000000");
System.out.println("bestPriceBigDecimal=" + myBigDecimal);
System.out.println("BigDecimal.valueOf(0.000000)=" + BigDecimal.valueOf(0.000000));
System.out.println(" equals=" + myBigDecimal.equals(BigDecimal.ZERO));
System.out.println("compare=" + (0 == myBigDecimal.compareTo(BigDecimal.ZERO)));

Результаты:

myBigDecimal=0.000000
BigDecimal.valueOf(0.000000)=0.0
 equals=false
compare=true

Хотя я понимаю преимущества сравнения BigDecimal, я бы не стал считать его интуитивно понятной конструкцией (как и операторы ==, ‹,>,‹ =,> =). Когда вы держите в голове миллион вещей (ну, семь вещей), тогда все, что вы можете уменьшить свою когнитивную нагрузку, - это хорошо. Итак, я создал несколько полезных функций для удобства:

public static boolean equalsZero(BigDecimal x) {
    return (0 == x.compareTo(BigDecimal.ZERO));
}
public static boolean equals(BigDecimal x, BigDecimal y) {
    return (0 == x.compareTo(y));
}
public static boolean lessThan(BigDecimal x, BigDecimal y) {
    return (-1 == x.compareTo(y));
}
public static boolean lessThanOrEquals(BigDecimal x, BigDecimal y) {
    return (x.compareTo(y) <= 0);
}
public static boolean greaterThan(BigDecimal x, BigDecimal y) {
    return (1 == x.compareTo(y));
}
public static boolean greaterThanOrEquals(BigDecimal x, BigDecimal y) {
    return (x.compareTo(y) >= 0);
}

Вот как их использовать:

    System.out.println("Starting main Utils");
    BigDecimal bigDecimal0 = new BigDecimal(00000.00);
    BigDecimal bigDecimal2 = new BigDecimal(2);
    BigDecimal bigDecimal4 = new BigDecimal(4);  
    BigDecimal bigDecimal20 = new BigDecimal(2.000);
    System.out.println("Positive cases:");
    System.out.println("bigDecimal0=" + bigDecimal0 + " == zero is " + Utils.equalsZero(bigDecimal0));
    System.out.println("bigDecimal2=" + bigDecimal2 + " <  bigDecimal4=" + bigDecimal4 + " is " + Utils.lessThan(bigDecimal2, bigDecimal4));
    System.out.println("bigDecimal2=" + bigDecimal2 + " == bigDecimal20=" + bigDecimal20 + " is " + Utils.equals(bigDecimal2, bigDecimal20));
    System.out.println("bigDecimal2=" + bigDecimal2 + " <= bigDecimal20=" + bigDecimal20 + " is " + Utils.equals(bigDecimal2, bigDecimal20));
    System.out.println("bigDecimal2=" + bigDecimal2 + " <= bigDecimal4=" + bigDecimal4 + " is " + Utils.lessThanOrEquals(bigDecimal2, bigDecimal4));
    System.out.println("bigDecimal4=" + bigDecimal4 + " >  bigDecimal2=" + bigDecimal2 + " is " + Utils.greaterThan(bigDecimal4, bigDecimal2));
    System.out.println("bigDecimal4=" + bigDecimal4 + " >= bigDecimal2=" + bigDecimal2 + " is " + Utils.greaterThanOrEquals(bigDecimal4, bigDecimal2));
    System.out.println("bigDecimal2=" + bigDecimal2 + " >= bigDecimal20=" + bigDecimal20 + " is " + Utils.greaterThanOrEquals(bigDecimal2, bigDecimal20));
    System.out.println("Negative cases:");
    System.out.println("bigDecimal2=" + bigDecimal2 + " == zero is " + Utils.equalsZero(bigDecimal2));
    System.out.println("bigDecimal2=" + bigDecimal2 + " == bigDecimal4=" + bigDecimal4 + " is " + Utils.equals(bigDecimal2, bigDecimal4));
    System.out.println("bigDecimal4=" + bigDecimal4 + " <  bigDecimal2=" + bigDecimal2 + " is " + Utils.lessThan(bigDecimal4, bigDecimal2));
    System.out.println("bigDecimal4=" + bigDecimal4 + " <= bigDecimal2=" + bigDecimal2 + " is " + Utils.lessThanOrEquals(bigDecimal4, bigDecimal2));
    System.out.println("bigDecimal2=" + bigDecimal2 + " >  bigDecimal4=" + bigDecimal4 + " is " + Utils.greaterThan(bigDecimal2, bigDecimal4));
    System.out.println("bigDecimal2=" + bigDecimal2 + " >= bigDecimal4=" + bigDecimal4 + " is " + Utils.greaterThanOrEquals(bigDecimal2, bigDecimal4));

Результаты выглядят так:

Positive cases:
bigDecimal0=0 == zero is true
bigDecimal2=2 <  bigDecimal4=4 is true
bigDecimal2=2 == bigDecimal20=2 is true
bigDecimal2=2 <= bigDecimal20=2 is true
bigDecimal2=2 <= bigDecimal4=4 is true
bigDecimal4=4 >  bigDecimal2=2 is true
bigDecimal4=4 >= bigDecimal2=2 is true
bigDecimal2=2 >= bigDecimal20=2 is true
Negative cases:
bigDecimal2=2 == zero is false
bigDecimal2=2 == bigDecimal4=4 is false
bigDecimal4=4 <  bigDecimal2=2 is false
bigDecimal4=4 <= bigDecimal2=2 is false
bigDecimal2=2 >  bigDecimal4=4 is false
bigDecimal2=2 >= bigDecimal4=4 is false
person Tihamer    schedule 24.05.2019
comment
Есть несколько ответов, объясняющих именно это. Какой смысл добавлять еще один ответ? Если у вас есть дополнительная информация, рекомендуется добавить новый ответ, но в этом посте это не так. - person Tom; 24.05.2019
comment
Дело принято. Однако, когда я что-то изучаю, мне нравится видеть как можно больше примеров, даже если они похожи. Для тебя, Том, я добавил свою библиотеку, которая показалась мне полезной. Ваш пробег может отличаться. :-) - person Tihamer; 29.05.2019

Просто хочу поделиться здесь некоторыми полезными расширениями для kotlin

fun BigDecimal.isZero() = compareTo(BigDecimal.ZERO) == 0
fun BigDecimal.isOne() = compareTo(BigDecimal.ONE) == 0
fun BigDecimal.isTen() = compareTo(BigDecimal.TEN) == 0
person Nokuap    schedule 17.01.2019

Простой и лучший способ для вашего примера:

BigDecimal price;

if(BigDecimal.ZERO.compareTo(price) == 0){
    
   //Returns TRUE

}
person Félix Maroy    schedule 30.11.2020


person    schedule
comment
Хотя этот код может ответить на вопрос, предоставляя дополнительный контекст относительно как и / или почему он решает проблему, повысит ценность ответа в долгосрочной перспективе. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для человека, который задает его сейчас! Пожалуйста, отредактируйте свой ответ, чтобы добавить пояснение и указать, какие ограничения и допущения применяются. Также не помешает упомянуть, почему этот ответ более уместен, чем другие. - person Dev-iL; 07.04.2017