简体   繁体   中英

BigDecimal if statement does not work with ! operator?

I have two BigDecimals , value1 and value2 . I want to divide value1 by value2 but obviously I don't want to do this if one of them is zero. So I wrote this simple if statement:

if(!value1.equals(0) && !value2.equals(0)){
  divide value1 by value2 blah blah blah
}

For some reason this if statement did not work.. even when one of the values equaled zero the equation would still be evaluated giving me an error because I was trying to divide with or by zero. I know that I can just use value1.compareTo(BigDecimal.valueOf(0) == 1 and get what I want doing that but I'm just curious as to why my first method didn't work.

Java treats objects of different types as different. This means that even if they represent something equivilent they are not the same.

What is "special" about BigDecimal is that even if the type is the same and the values are equivelent, but have different scales, they are still not "equals"

Double d = 0.0;
Integer i = 0;
System.out.println(d + " equals " + i + " is " + (d.equals(i)));

BigDecimal bd2 = new BigDecimal("0.00");
BigDecimal bd3 = new BigDecimal("0.000");

System.out.println(bd2 + " equals " + d + " is " + (bd2.equals(d)));
System.out.println(bd2 + " equals " + bd2 + " is " + (bd2.equals(bd2)));
System.out.println(bd2 + " equals " + bd3 + " is " + (bd2.equals(bd3)));

prints

0.0 equals 0 is false
0.00 equals 0.0 is false
0.00 equals 0.00 is true
0.00 equals 0.000 is false

The way around this is to use compareTo which adjusts for the scale and gives you a more natural comparison.

System.out.println(bd2 + " compareTo " + BigDecimal.ZERO + " is " + (bd2.compareTo(BigDecimal.ZERO )));
System.out.println(bd3 + " compareTo " + BigDecimal.ZERO + " is " + (bd3.compareTo(BigDecimal.ZERO )));

prints

0.00 compareTo 0 is 0
0.000 compareTo 0 is 0

This means if you are going to use BigDecimal you need to write

if(value1.compareTo(BigDecimal.ZERO) != 0 && value2.compareTo(BigDecimal.ZERO) != 0) {

Personally, I prefer to use double which is simpler and faster. The only down side is you have to manage the rounding yourself.

double div = value1 / value2;
if (0 < div && div < SOME_UPPER_SENSIBLE_LIMIT) {
   // division was ok.
   System.out.printf("%.4f", div); // print with rounding.

Use this instead.

  if(BigDecimal.ZERO.compareTo(value1) != 0 && BigDecimal.ZERO.compareTo(value2) != 0) 
  {
     ....
  }

equals will not work.

Check this: public boolean equals(Object x) Compares this BigDecimal with the specified Object for equality. Unlike compareTo, this method considers two BigDecimal objects equal only if they are equal in value and scale (thus 2.0 is not equal to 2.00 when compared by this method).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM