如何在Java中检查BigDecimal变量== 0?


202

我有以下Java代码;

BigDecimal price; // assigned elsewhere

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

编写if条件的最佳方法是什么?


12
建议使用BigDecimal的.equals()方法获得许多答案。但是该方法考虑了比例,因此不等同于使用compareTo()。
GriffeyDog 2012年

Answers:


472

使用compareTo(BigDecimal.ZERO)代替equals()

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

BigDecimal常量进行比较BigDecimal.ZERO避免了必须构造new BigDecimal(0)每个执行。

仅供参考,BigDecimal也有常量BigDecimal.ONEBigDecimal.TEN为您提供方便。


注意!

您无法使用的原因BigDecimal#equals()是它考虑了比例

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

BigDecimal.ZERO.compareTo(price)== 0
Jackkobec

97

另外,可以使用signum()

if (price.signum() == 0) {
    return true;
}

21
也许速度更快,但是compareTo(BigDecimal.ZERO)更具可读性。
ElYeante 2014年

@ElYeante,您始终可以使用方法进行包装,该方法具有更易读的名称,甚至可以描述您的业务逻辑的一部分,并通过这种比较进行连接
WeGa 2016年

3
不幸的是,signum()并不是null安全的,而compareTo是,例如BigDecimal.ZERO.compareTo()进行比较时,请注意
WeGa

15
@WeGa这是不对的:BigDecimal.ZERO.compareTo(null)将引发NPE
ACV

5
@ACV,感谢您的警惕。看一下源代码,compareTo()只期望确实为非null参数。
WeGa


5

我通常使用以下内容:

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

5

另外,我认为值得一提的是,BigDecimal类中equals和compareTo方法的行为彼此不一致

这基本上意味着:

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

因此,您必须非常小心someValue变量的小数位数,否则会得到意外的结果。


5

您将要使用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()


Java BigDecimal的equals和行为compareTo并不像您想象的那样。docs.oracle.com/javase/1.5.0/docs/api/java/math/...
nhahtdh

想要解释您的意思而不是链接到文档?我建议的内容应适用于OP。
NominSim 2012年

实际上,Edwin Dalorzo的回答很好地解释了这一点。equals考虑到规模,这不是我们想要的。
nhahtdh

@nhahtdh感谢您提供的信息,尽管在某些情况下equals 使用而不是compareTo()。OP并没有指定他正在使用哪种数学类型,因此您是对的,最好给他两个选择。
NominSim 2012年

3

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

1
有很多答案可以解释这一点。添加另一个答案有什么意义?如果您还有其他信息,那么最好添加新答案,但是本文中并非如此。
汤姆(Tom),

点了。但是,当我学习一些东西时,即使它们很相似,我也希望看到尽可能多的示例。对您而言,汤姆,我添加了我认为有用的库。您的里程可能会有所不同。:-)
Tihamer

0

只想在这里分享一些有用的Kotlin扩展

fun BigDecimal.isZero() = compareTo(BigDecimal.ZERO) == 0
fun BigDecimal.isOne() = compareTo(BigDecimal.ONE) == 0
fun BigDecimal.isTen() = compareTo(BigDecimal.TEN) == 0

-2
BigDecimal.ZERO.setScale(2).equals(new BigDecimal("0.00"));

1
尽管此代码可以回答问题,但提供有关如何和/或为什么解决问题的其他上下文将提高答案的长期价值。请记住,您将来会为读者回答问题,而不仅仅是现在问的人!请编辑您的答案以添加说明,并指出适用的限制和假设。提一下为什么这个答案比其他答案更合适也无妨。
Dev-iL

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.