Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算,常用BigDecimal来存金额。在对金额进行校验的时候发生异常,后来发现是比较大小的方法equals导致的。

BigDecimal的equals方法源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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());
}

equals方法不仅比较了两个数的大小,还比较了精度是否相等,当出现5和5.0这种,就会被认为是不相等的。

compareTo的源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public int compareTo(BigDecimal val) {
// Quick path for equal scale and non-inflated case.
if (scale == val.scale) {
long xs = intCompact;
long ys = val.intCompact;
if (xs != INFLATED && ys != INFLATED)
return xs != ys ? ((xs > ys) ? 1 : -1) : 0;
}
int xsign = this.signum();
int ysign = val.signum();
if (xsign != ysign)
return (xsign > ysign) ? 1 : -1;
if (xsign == 0)
return 0;
int cmp = compareMagnitude(val);
return (xsign > 0) ? cmp : -cmp;
}

compareTo方法只比较了两个数的大小,没有比较精度是否相等,当出现5和5.0这种,就会被认为是相等的。

BigDecimal常用方法:

  1. add(BigDecimal):BigDecimal对象中的值相加,然后返回这个对象。
  2. subtract(BigDecimal):BigDecimal对象中的值相减,然后返回这个对象。
  3. multiply(BigDecimal):BigDecimal对象中的值相乘,然后返回这个对象。
  4. divide(BigDecimal):BigDecimal对象中的值相除,然后返回这个对象。
  5. toString():将BigDecimal对象的数值转换成字符串。
  6. doubleValue():将BigDecimal对象中的值以双精度数返回。
  7. floatValue():将BigDecimal对象中的值以单精度数返回。
  8. longValue():将BigDecimal对象中的值以长整数返回。
  9. intValue():将BigDecimal对象中的值以整数返回。

相关文章:http://blog.csdn.net/lisongjia123/article/details/51232657