new BigDecimal时,结果存在误差的问题

昨天有个需求上线之后,今天进行验证时发现,根据接口返回的数据,在处理之后下发短信的时候,明明从接口返回的是541.04,结果下发的却是541.03,附上我的代码:

这个时候我意识到可能是精度存在问题,因为使用new BigDecimal是之前就用的,这个方法也就是这么写的,我只是复制过来的。并且开发完之后测试测了很长时间都没有发现这个问题,由于我对数字处理接触的不多,于是就找到了度娘,其中比较靠上的回答说是因为ROUND_DOWN的问题,我本人是质疑的,因为这是取整的问题,源数字就是两位数,不存在往上取整还是往下取整,在评论区的一个评论让我眼前一亮,他的意思就是new BigDecimal里面传字符串就好了,我试了一下,果然输出结果正确,那么为什么呢,我带着好奇心终于慢慢找到了。

 

 

BigDecimal提供了丰富的构造函数,可以通过int、long、double、String等来构造一个BigDecimal对象。

但是,使用double作为参数的构造函数,无法精确构造一个BigDecimal对象,需要自己指定一个上下文的环境,也就是指定精确位。 
例如:

BigDecimal bg = new BigDecimal(1.1);
System.out.println(bg.toString());

运行结果:
1.100000000000000088817841970012523233890533447265625

 

所以,通常情况下,我们会使用String对象作为参数来构造一个精确的BigDecimal对象。 
下面提供的三种方法都是可以的

//方法一
BigDecimal bg1 = new BigDecimal("1.1");
//方法二
BigDecimal bg2 = new BigDecimal(Double.toString(1.1));
//方法三
BigDecimal bg3 = BigDecimal.valueOf(1.1);
 
System.out.println(bg1.toString());
System.out.println(bg2.toString());
System.out.println(bg3.toString());
 
运行结果:
1.1
1.1
1.1

附: 
BigDecimal.value(double val)方法为什么可以呢? 
看看下面的源码,大家应该就清楚了:

public static BigDecimal valueOf(double val) {
  return new BigDecimal(Double.toString(val));
 }

参考:https://blog.csdn.net/u011983531/article/details/67637757

posted @ 2021-05-14 16:29  快乐风男  阅读(594)  评论(0)    收藏  举报