欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > 关于BigDecimal计算除法的精度问题

关于BigDecimal计算除法的精度问题

2025/10/23 10:00:48 来源:https://blog.csdn.net/weixin_45614626/article/details/147255682  浏览:    关键词:关于BigDecimal计算除法的精度问题

看一下下边的代码:

 @Testpublic void calTest() {BigDecimal realGmv = BigDecimal.valueOf(30598.0);BigDecimal gmvTarget = BigDecimal.valueOf(275800.00);int assessDayCnt = 15;int periodDayCnt = 30;BigDecimal middle = realGmv.multiply(BigDecimal.valueOf(100)).multiply(BigDecimal.valueOf(assessDayCnt)).divide(BigDecimal.valueOf(periodDayCnt), RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP);BigDecimal ratio = middle.divide(gmvTarget, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP);System.out.println(middle);System.out.println(ratio);BigDecimal middle2 = realGmv.multiply(BigDecimal.valueOf(100)).multiply(BigDecimal.valueOf(assessDayCnt)).divide(BigDecimal.valueOf(periodDayCnt), RoundingMode.HALF_UP);BigDecimal ratio2 = middle2.divide(gmvTarget, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP);System.out.println(middle2);System.out.println(ratio2);BigDecimal middle3 = gmvTarget.multiply(BigDecimal.valueOf(periodDayCnt));BigDecimal ratio3 = realGmv.multiply(BigDecimal.valueOf(100)).multiply(BigDecimal.valueOf(assessDayCnt)).divide(middle3, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP);System.out.println(middle3);System.out.println(ratio3);}

这三种计算方法的输出是:


1529900.00
5.55
1529900.0
5.50
8274000.0
5.50

最终输出结果大相径庭,最根本的原因就是后两种计算方式中,中间的被除数的精度是小数点后一位,BigDecimal在做除法运算的时候有一个保留位数的规则:

BigDecimal 除法规则:结果 scale = max(被除数.scale() - 除数.scale(), 0) + 1

所以后两种其实是divide的时候结果算出来时5.547-》保留一位变成5.5然后setScale生效,补一个0变成5.50。
第一种写法恰好对也是因为第一次是一个整除,所以直接setScale没问题,假如不是整除也会有问题。
最简单的解决办法就是在divide的方法里加上结果位数的指定,比如下边:

BigDecimal middle4 = realGmv.multiply(BigDecimal.valueOf(100)).multiply(BigDecimal.valueOf(assessDayCnt)).divide(BigDecimal.valueOf(periodDayCnt), 10, RoundingMode.HALF_UP);BigDecimal ratio4 = middle2.divide(gmvTarget, 10, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP);System.out.println(middle4);System.out.println(ratio4);

随后在加上setScale就不会有问题了。简直不要太隐蔽。。。。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词