解决double的值相加的问题

Posted donghaibin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决double的值相加的问题相关的知识,希望对你有一定的参考价值。

针对double类型的计算的问题之一:

public class DoubleCaculator {
    double price = 0.38;
    int count = 3;
    
    @Test
    public void demo1() {
        //结果:1.1400000000000001
        System.out.println(price * count);
    }
}
    @Test
    public void demo2() {
        //bigDecimal的字符串的构造完美解决了double计算的问题
        BigDecimal bdP = new BigDecimal(price);
        BigDecimal bdc = new BigDecimal(count);
        BigDecimal add = bdP.multiply(bdc);
        System.out.println(add.doubleValue());
    }

此结果是:2.2800000000000002

从上面两个的结果,显然与我们想要的结果有点不一样,如果是针对金融方面的话,那么一个小数点的问题就会影响很大,那么对于这样的问题,我们要如何的解决哪?

答:BigDecimal这个类。

那为啥上面使用了这个BigDecimal为啥还会出现这个问题?

答:传入的参数有问题。

源码的注释说明:如果B中传入的为double类型的值时的解释

The results of this constructor can be somewhat unpredictable.
     * One might assume that writing {@code new BigDecimal(0.1)} in
     * Java creates a {@code BigDecimal} which is exactly equal to
     * 0.1 (an unscaled value of 1, with a scale of 1), but it is
     * actually equal to
     * 0.1000000000000000055511151231257827021181583404541015625.
     * This is because 0.1 cannot be represented exactly as a
     * {@code double} (or, for that matter, as a binary fraction of
     * any finite length).  Thus, the value that is being passed
     * <i>in</i> to the constructor is not exactly equal to 0.1,
     * appearances notwithstanding.
     *

以及给出的最佳的解决方法:

The {@code String} constructor, on the other hand, is
     * perfectly predictable: writing {@code new BigDecimal("0.1")}
     * creates a {@code BigDecimal} which is <i>exactly</i> equal to
     * 0.1, as one would expect.  Therefore, it is generally
     * recommended that the {@linkplain #BigDecimal(String)
     * <tt>String</tt> constructor} be used in preference to this one.
     *

所以上面的代码如果将传入的double类型的值转换成字符串的话,那么问题就解决了:

    @Test
    public void demo2() {
        //bigDecimal的字符串的构造完美解决了double计算的问题
        BigDecimal bdP = new BigDecimal(price + "");
        BigDecimal bdc = new BigDecimal(count + "");
        BigDecimal add = bdP.multiply(bdc);
        System.out.println(add.doubleValue());
    }

 

以上是关于解决double的值相加的问题的主要内容,如果未能解决你的问题,请参考以下文章

多个double相加Util

如何把List里面的值循环相加

关于double类型数字相加位数发生变化的问题

Js中带有小数的值相加减的解决方案

JAVA中double类型数据相加

在这个 spark 代码片段中 ordering.by 是啥意思?