BigDecimal
一、通过浮点数创建
建议使用BigDecimal.value(1.01)
不建议用new BigDecimal(1.01)
创建
原因:new BigDecimal时,1.01已经是浮点类型了,已经存在了精度丢失。而BigDecimal.value()方法内部将参数先转化为字符串,就不会存在精度问题
public static BigDecimal valueOf(double val) {
return new BigDecimal(Double.toString(val));
}
二、比较大小
建议使用:BigDecimal.compareTo
不建议用:BigDecimal.equals
原因:equals方法会进行值和精度的比较,也就是说 BigDecimal.valueOf(1.1).equals(BigDecimal.valueOf(1.10))是不相等的
@Override
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());
}
三、除法必须设置精度
@Test
public void test3(){
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("3.0");
a.divide(b);
}
以上程序执行结果会抛出异常java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
原因是因为1/3是除不尽的,而我们需要的是一个确切的数,就会抛出ArithmeticException异常。
正确写法:
@Test
public void test3(){
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("3.0");
BigDecimal c = a.divide(b, 2,RoundingMode.HALF_UP);
System.out.println(c);
}
四、toString的坑
三种toString方法:
toPlainString()
:不使用任何科学计数法
toString()
:在必要的时候使用科学计数法
toEngineeringString()
:在必要的时候使用工程计数法。类似于科学计数法,只不过指数的幂都是3的倍数,这样方便工程上的应用,因为在很多单位转换的时候都是10^3
网友评论