class="java" name="code">BigDecimal.valueOf(0.03f)
最近工作中一个同事用到了上述用法,感觉会丢失精度,于是把BigDecimal这块使用过程中踩过的坑稍微整理一下。
?
System.out.println(new BigDecimal("0.03")); System.out.println(new BigDecimal(3)); System.out.println(new BigDecimal(0.03)); System.out.println(BigDecimal.valueOf(3L)); System.out.println(BigDecimal.valueOf(0.03)); System.out.println(BigDecimal.valueOf(0.03f));
?
上述你能准确说出运行结果么?
0.03 3 0.0299999999999999988897769753748434595763683319091796875 3 0.03 0.029999999329447746
?
最常用的标准构造器为:
public BigDecimal(String val);
另一个也基本一致:? ?
public static BigDecimal valueOf(double val) { return new BigDecimal(Double.toString(val)); }
其他构造器使用不小心的话就可能产生问题,这块后续对java中的数值类型精度方面做个细致的学习和整理。
BigDecimal.valueOf(0.03f)这个数值不符合预期是float转double的时候丢失精度了,跟BigDecimal无关。
?
?
BigDecimal a = new BigDecimal("1.23"); BigDecimal b = new BigDecimal("1.230"); System.out.println(a.equals(b)); //false
结果竟不是预期的true。
equals是比较内容,自然不一样。BigDecimal的比较要用compareTo
System.out.println(a.compareTo(b)); //0表示相等
?
?
BigDecimal c = new BigDecimal("1.23"); BigDecimal d = new BigDecimal("1.23"); c.add(d); System.out.println(c);
?结果是2,46么?
显然不是,仍然是1.23
?
BigDecimal加减乘除最终都返回的是一个新的BigDecimal对象,c.add(d);虽然做了加法操作,但是c并没有保存加操作后的值,正确的用法应该是c=c.add(d)。
?
?
?
System.out.println(new BigDecimal("100").divide(new BigDecimal("12")));?结果直接抛异常了。
?
BigDecimal的除法要养成习惯去设置精度,以免出现无限循环小数而抛异常。
?
new BigDecimal("100").divide(new BigDecimal("12").setScale(2, BigDecimal.ROUND_HALF_DOWN)
System.out.println(0.99999999f == 1f); //true System.out.println(0.99999999 == 1); //false?
note:关于java数值精度(double、float、BigDecimal)这块后续再整理一次,如果不明白细节,很容易犯错误。