public static void main(String[] args) {
BigDecimal qtyActual = new BigDecimal(0).setScale(2,BigDecimal.ROUND_UP);
System.out.println(qtyActual.equals(BigDecimal.ZERO));
qtyActual = new BigDecimal(0);
System.out.println(new BigDecimal(0).equals(BigDecimal.ZERO));
qtyActual = new BigDecimal(0);
System.out.println(new BigDecimal(0.00).equals(BigDecimal.ZERO));
}
上述代码输出的对别结果是false;true;true
虽然qtyActual 这个参数的值一直都是0,但是结果却不同,因为BigDecimal的equals方法在对比两个值时会对比两数的小数位数,equals源码如下
public boolean equals(Object x) {
if (!(x instanceof BigDecimal))
return false;
BigDecimal xDec = (BigDecimal) x;
if (x == this)
return true;
//对比小数位数
if (scale != xDec.scale)
return false;
long s = this.intCompact;
long xs = xDec.intCompact;
if (s != INFLATED) {
if (xs == INFLATED)
xs = compactValFor(xDec.intVal);
return xs == s;
} else if (xs != INFLATED)
return xs == compactValFor(this.intVal);
return this.inflated().equals(xDec.inflated());
}
所以,第一个输出结果位false和第二个输出结果为true就可以解释通了,但是第三个比较代码0.00 和 0的小数位不同啊,第三个输出语句不应该是false吗?
截取BigDecimal构造方法的一部分
public BigDecimal(double val, MathContext mc) {
if (Double.isInfinite(val) || Double.isNaN(val))
throw new NumberFormatException("Infinite or NaN");
// Translate the double into sign, exponent and significand, according
// to the formulae in JLS, Section 20.10.22.
long valBits = Double.doubleToLongBits(val);
int sign = ((valBits >> 63) == 0 ? 1 : -1);
int exponent = (int) ((valBits >> 52) & 0x7ffL);
long significand = (exponent == 0
? (valBits & ((1L << 52) - 1)) << 1
: (valBits & ((1L << 52) - 1)) | (1L << 52));
exponent -= 1075;
// At this point, val == sign * significand * 2**exponent.
/*
* Special case zero to supress nonterminating normalization and bogus
* scale calculation.
*/
if (significand == 0) {
this.intVal = BigInteger.ZERO;
this.scale = 0;
this.intCompact = 0;
this.precision = 1;
return;
}
可以看到this.scale = 0;而 BigDecimal.ZERO的代表的数是scale为0的数,所以第三个对比结果为true
BigDecimal类型数的值对比可以使用compareTo(),两数相同返回0