Java中中BigDecimal精度和相等比较的坑精度和相等比较的坑
BigDecimal是一种精确的数字类,一般用于高精度的开发领域中,例如银行。下面这篇文章主要给大家介绍了
关于Java中BigDecimal精度和相等比较的坑的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以
参考下
为什么要有为什么要有BigDecimal ,他是干什么的,他是干什么的
float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较
为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。但是,
商业计算往往要求结果精确,这时候就要使用BigDecimal啦。
什么是什么是BigDecimal
BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果
为负数,则将该数的非标度值乘以 10 的负scale 次幂。因此,BigDecimal表示的数值是(unscaledValue × 10-scale)。
本文将给大家详细介绍关于Java中BigDecimal精度和相等比较的坑,下面话不多说了,来一起看看详细的介绍吧
先想一下,创建先想一下,创建BigDecimal对象的时候一般是怎么创建的?对象的时候一般是怎么创建的?
new一个,传进去值
BigDecimal.valueOf方法,传进去值
作为一个数字类型,经常有的操作是比较大小,有一种情况是比较是否相等。用equal方法还是compareTo方法?这里就是一
个大坑
//new 传进去一个double
BigDecimal newZero = new BigDecimal(0.0);
System.out.println(BigDecimal.ZERO.equals(newZero));
//new 传进去一个字符串
BigDecimal stringNewZero = new BigDecimal("0.0");
System.out.println(BigDecimal.ZERO.equals(stringNewZero));
//valueOf 传进去一个double
BigDecimal noScaleZero = BigDecimal.valueOf(0.0);
System.out.println(BigDecimal.ZERO.equals(noScaleZero));
//valueOf 传进去一个double,再手动设置精度为1
BigDecimal scaleZero = BigDecimal.valueOf(0.0).setScale(1);
System.out.println(BigDecimal.ZERO.equals(scaleZero));
用于比较的值全都是0,猜一猜上面几个equals方法返回的结果是什么?全都是true?no no no...
true
false
false
false
惊不惊喜,意不意外?原因是什么呢?看一下BigDecimal的equals方法的实现:
public boolean equals(Object x) {
//类型不同,直接返回false
if (!(x instanceof BigDecimal))
return false;
BigDecimal xDec = (BigDecimal) x;
//同一个对象,直接返回true
if (x == this)
return true;
//精度不同,直接返回false!!
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());
}