BigDecimal进行浮点数精确计算错误用法和正确用法

前言

通常商业计算涉及到小数的,我们都会使用BigDecimal来完成加减乘除运算。但是利用BigDecimal进行浮点数精确运算时,需要注意使用正确的方法。如果方法选择不当,依旧会发生错误。

发现问题

在这里插入图片描述
测试BigDecimal的两种构造方法,发现浮点运算的结果不同。
利用BigDecimal.valueOf方法构造对象的方法,获得的浮点数发生了精度异常。
利用new BigDecimal(String val)方法,运算正确。

分析原因

查看BigDecimal.valueOf源码,我们可以发现问题。BigDecimal.valueOf(9.9f),实际调用的方法是:java.math.BigDecimal#valueOf(double)。如下图所示。
在这里插入图片描述
比我们想象的多了一步强制类型转换的动作。9.9f会被强制转换成double类型。测试这个强制转换,我们可以发现问题,其实出在强制转换这里。强制转换结果如下图所示。
在这里插入图片描述

拓展

假如参数是double类型,我们使用BigDecimal.valueOf(…)可以吗?
在这里插入图片描述
看结果是没问题的。但是,注意BigDecimal.valueOf(…)的源码,其内部依然是把入参转换了double数据对应的字符串。
假如直接使用new BigDecimal(double val)构造函数来进行运算,则会发现计算结果发生来精度异常。如下图所示。
在这里插入图片描述
可以看到jdk内部的注释,已经说明,new BigDecimal(double val)方法得到的结果是不可预知的。推荐使用入参类型为String的构造函数来进行浮点数的精确计算。
在这里插入图片描述

总结

1、在使用BigDecimal进行科学运算的时候,我们需要清楚,BigDecimal.valueOf(…)和new BigDecimal(…)的使用效果不同。当BigDecimal.valueOf(…)的入参是float类型时,BigDecimal会把入参强制转换成double类型。
2、使用new BigDecimal(String val)来获得浮点数对应的BigDecimal对象,进而完成浮点数精确运算。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值