当前位置: 主页 > JAVA语言

java除法保留两位小数-int除法保留两位小数

发布时间:2023-05-21 07:09   浏览次数:次   作者:佚名

BigDecimal除法的精度问题

java除法保留两位小数_int除法保留两位小数_java除法保留两位小数

在使用BigDecimal的除法时,遇到一个鬼畜的问题,本以为的精度计算,结果使用返回0,当然最终发现还是自己的使用姿势不对导致的,因此记录一下java除法保留两位小数,避免后面重蹈覆辙

I. 问题抛出

在使用BigDecimal做高精度的除法时,一不注意遇到了一个小问题,如下

java除法保留两位小数_java除法保留两位小数_int除法保留两位小数

上面的输出是什么 ?

java除法保留两位小数_int除法保留两位小数_java除法保留两位小数

为什么前面两个会是0呢,如果直接是 541253 / 12389431 = 0 倒是可以理解, 但是BigDecimal不是高精度的计算么,讲道理不应该不会出现这种整除的问题吧

我们知道在BigDecimal做触发时,可以指定保留小数的参数java除法保留两位小数,如果加上这个,是否会不一样呢?

java除法保留两位小数_java除法保留两位小数_int除法保留两位小数

输出结果为:

java除法保留两位小数_java除法保留两位小数_int除法保留两位小数

所以说在指定了保留小数之后,则没有问题,所以大胆的猜测一下,是不是上面的几种case中,由于scale值没有指定时,默认值不一样,从而导致最终结果的精度不同呢?

简单的深入源码分析一下,执行的方式为 origin.divide(now, RoundingMode.HALF_UP);, 所以这个scale参数就瞄准origin对象,而这个对象,就只能去分析它的构造了,因为没有其他的地方使用

II. 源码定位

1. 整形传参构造

分析下面这一行, 直接进入源码

int除法保留两位小数_java除法保留两位小数_java除法保留两位小数

很明显的int传参构造,进去简单看一下

int除法保留两位小数_java除法保留两位小数_java除法保留两位小数

so,很明确的知道默认的scale为0,也就是说当origin为正数时,以它进行的除法,不现实指定scale参数时,最终返回的都是没有小数的,同样看一眼,还有long的传参方式, BigInteger也一样

2. 浮点传参

接下来就是浮点的scale默认值确认了,这个构造相比前面的复杂一点,源码就不贴了,太长,也看不太懂做了些啥,直接用猥琐一点的方式,进入debug模式,单步执行

int除法保留两位小数_java除法保留两位小数_java除法保留两位小数

根据debug的结果,第一个,scale为0; 第二个scale为29, 第三个scale为0

java除法保留两位小数_java除法保留两位小数_int除法保留两位小数

java除法保留两位小数_int除法保留两位小数_java除法保留两位小数

java除法保留两位小数_int除法保留两位小数_java除法保留两位小数

3. String传参

依然是一大串的逻辑,同样采用单步debug的方式试下

java除法保留两位小数_java除法保留两位小数_int除法保留两位小数

上面三个的scale都是1

java除法保留两位小数_java除法保留两位小数_int除法保留两位小数

4. 小结

最后贴一张乘法的图作为收尾

java除法保留两位小数_int除法保留两位小数_java除法保留两位小数

II. 其他

1. 一灰灰Blog:

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛