Bigdecimal除法异常Non-terminating decimal expansion

Bigdecimal除法异常Non-terminating decimal expansion文章目录异常分析解决措施思考总结异常分析其实提示信息已经很明显了,出现了无限循环小数,无法返回bigdecimal的值,回顾一下项目中的代码方式:returnnewBigDecimal(baseMonth).divide(newBigDecimal(workDay)).setScale(2,BigDecimal.ROUND_HALF_UP);代码如上,使用baseMonth除以workDay,返回的值按照四舍五入的方式保留两位小数。但是还是出现了异常,原因就在于divide的调用方式。解

大家好,又见面了,我是你们的朋友全栈君。

异常分析

其实提示信息已经很明显了,出现了无限循环小数,无法返回bigdecimal的值,回顾一下项目中的代码方式:

return new BigDecimal(baseMonth).divide(new BigDecimal(workDay)).setScale(2, BigDecimal.ROUND_HALF_UP);

代码如上,使用baseMonth除以workDay,返回的值按照四舍五入的方式保留两位小数。但是还是出现了异常,原因就在于divide的调用方式。

解决措施

使用divide的重载方法:divide(BigDecimal divisor, int scale, int roundingMode)

return new BigDecimal(baseMonth).divide(new BigDecimal(workDay), 2, BigDecimal.ROUND_HALF_UP);

备注:小数点后的精确类型,可参考JDK源码,以下为简要的截图举例说明
在这里插入图片描述

思考

问题是解决了,但是我还在想我第一种方式,显然,我在编码的时候也想到了指定小数点保留以及精确方式,但是还是会出现异常,那Bigdecimal提供的setScale的方法是在什么场景下使用呢?我猜想当被除数除以除数结果为有限小数时,可以使用Bigdecimal的setScale方法,那来验证一下

public static void main(String[] args) { 
   
        //有限小数
        BigDecimal a = new BigDecimal("2");
        BigDecimal b = new BigDecimal("100");
        System.out.println(a.divide(b).setScale(2, RoundingMode.HALF_UP));
    }

结果为:0.02
当使用.setScale(3, RoundingMode.HALF_UP)时,则结果为0.020;

可见,以上猜想是正确的,即当bigdecimal进行除法运算时,则会发生小数点溢出的情况,此时,可能会出现无限小数,抛出异常,建议使用divide(BigDecimal divisor, int scale, int roundingMode)方式进行除法运算。

总结

  • bigdecimal的乘法和除法都会导致小数点的溢出,建议指定位数和精确方式
  • bigdecimal的.setScale方法,用于指定有限小数
  • 不建议使用float、double进行bigdecimal的构建,会导致精度的紊乱,建议采用int和string
  • 在java程序中的小数计算,比如银行交易额、支付金额等都使用的是bigdecimal类型
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/151201.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号