BigDecimal常见使用误区_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > BigDecimal常见使用误区

BigDecimal常见使用误区

 2016/6/15 5:35:08  welcomezhang  程序员俱乐部  我要评论(0)
  • 摘要:BigDecimal.valueOf(0.03f)最近工作中一个同事用到了上述用法,感觉会丢失精度,于是把BigDecimal这块使用过程中踩过的坑稍微整理一下。使用误区一:初始化System.out.println(newBigDecimal("0.03"));System.out.println(newBigDecimal(3));System.out.println(newBigDecimal(0.03));System.out.println(BigDecimal.valueOf(3L
  • 标签:使用 误区 Decimal
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")));
?结果直接抛异常了。
异常 如下:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

?

原理分析

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)这块后续再整理一次,如果不明白细节,很容易犯错误

发表评论
用户名: 匿名