java——浮点数不精确的解决办法

问题案例

由于计算机系统的特性,java浮点数(float、double)的精度有时候会不准确,案例代码如下:

        System.out.println(0.09 + 0.01);
        System.out.println(1.0 - 0.32);
        System.out.println(1.015 * 100);
        System.out.println(1.301 / 100);

输出结果


输出结果

发生了计算结果精度有误差的问题

解决办法

利用BigDecimal类(包:java.math.BigDecimal)解决计算误差问题

  • 1、加减乘解决办法
    BigDecimal类创建对象时有多个重载方法,推荐使用参数为String的构造方法创建对象进行计算,因为String可以表示无限长度的数,而int、long、float等表示的数的范围是有限的,代码如下:
        /** 加 */
        BigDecimal b1 = new BigDecimal("0.09");
        BigDecimal b2 = new BigDecimal("0.01");
        BigDecimal bigAdd = b1.add(b2);
        System.out.println(bigAdd);
        
        /** 减 */
        BigDecimal b3 = new BigDecimal("1");
        BigDecimal b4 = new BigDecimal("0.32");
        BigDecimal bigSub = b3.subtract(b4);
        System.out.println(bigSub);
        
        /** 乘 */
        BigDecimal b5 = new BigDecimal("1.015");
        BigDecimal b6 = new BigDecimal("100");
        BigDecimal bigMul = b5.multiply(b6);
        System.out.println(bigMul);

输出结果


输出结果
  • 2、除解决方法
    为什么除与加减乘不一样,因为除会涉及到除不尽的问题,小数点后是无限的,所以它不知道该如何显示,就会抛出异常,例如:
        BigDecimal b1 = new BigDecimal("1.301");
        BigDecimal b2 = new BigDecimal("101");
        BigDecimal bigDiv = b1.divide(b2);
        System.out.println(bigDiv);

输出结果


输出结果

所以应该用divide()的一个重载方法:public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode),来设置精确到多少位:

        /** 除
         *  参数1:被除数
         *  参数2:精确到第N位
         *  参数3:N位后的数的取舍方式,填BigDecimal定义好的常量
         *          通常用以下三个常量:
         *          ROUND_HALF_UP    表示N位后的那一位四舍五入
         *          ROUND_UP          表示N位后的那一位直接入
         *          ROUND_DOWN      表示N位后的那一位直接舍
         *          当然,取舍完后,第N位之后的通通丢弃
         */
        BigDecimal b1 = new BigDecimal("1.301");
        BigDecimal b2 = new BigDecimal("101");
        //精确到第5位
        BigDecimal bigDiv = b1.divide(b2,5,BigDecimal.ROUND_HALF_UP);
        //精确到第4位,第5位四舍五入
        BigDecimal bigDiv1 = b1.divide(b2,4,BigDecimal.ROUND_HALF_UP);
        //精确到第4位,第5位直接入
        BigDecimal bigDiv2 = b1.divide(b2,4,BigDecimal.ROUND_UP);
        //精确到第4位,第5位直接舍
        BigDecimal bigDiv3 = b1.divide(b2,4,BigDecimal.ROUND_DOWN);
        System.out.println(bigDiv);
        System.out.println(bigDiv1);
        System.out.println(bigDiv2);
        System.out.println(bigDiv3);

输出结果


输出结果
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容