BigDecimal对象间相加结果不准(常见错误)

【问题代码】:

package demo;

import java.math.BigDecimal;

public class demo9 {
    public BigDecimal add(double value1,double value2){
        BigDecimal b1=new BigDecimal(value1);
        BigDecimal b2=new BigDecimal(value2);
        return b1.add(b2);
    }
    public static void main(String[] args) {
        demo9 b=new demo9();
        System.out.println("两个数相加结果:"+b.add(-1,8));//两个数相加结果:7
        System.out.println("两个数相加结果:"+b.add(-1.0,8.0));//两个数相加结果:7
        System.out.println("两个数相加结果:"+b.add(-1.5,8));//两个数相加结果:6.5
        System.out.println("两个数相加结果:"+b.add(-1.5,8.9));
        //两个数相加结果:7.4000000000000003552713678800500929355621337890625
        System.out.println("两个数相加结果:"+b.add(0,8.9));
        //两个数相加结果:8.9000000000000003552713678800500929355621337890625
    }
}

【问题描述】:

在上面代码中我们可以看到System.out.println("两个数相加结果:"+b.add(-1.5,8.9));的结果为7.4000000000000003552713678800500929355621337890625,和正确的结果不一样,这是为什么?

【问题解析】:

参数类型为double的构造方法的结果有一定的不可预知性。在Java中new BigDecimal(8.9)所创建的BigDecimal并不是正好等于8.9,而实际上等于8.9000000000000003552713678800500929355621337890625。这是因为8.9无法准确地表示为double(或者说对于这种情况,不能表示为任何有限长度的二进制小数),而String的构造方法是完全可预知的,所以利用Double的toString方法将8.9、-1.5转化为字符串,就不会发生精确不准的情况了。

【代码修正】:

package demo;

import java.math.BigDecimal;

public class demo10 {
    public BigDecimal add(double value1,double value2){
        BigDecimal b1=new BigDecimal(Double.toString(value1));
        BigDecimal b2=new BigDecimal(Double.toString(value2));
        return b1.add(b2);
    }
    public static void main(String[] args) {
        demo10 b=new demo10();
        System.out.println("两个数相加结果:"+b.add(-1,8));//两个数相加结果:7.0
        System.out.println("两个数相加结果:"+b.add(-1.0,8.0));//两个数相加结果:7.0
        System.out.println("两个数相加结果:"+b.add(-1.5,8));//两个数相加结果:6.5
        System.out.println("两个数相加结果:"+b.add(-1.5,8.9));//两个数相加结果:7.4
        System.out.println("两个数相加结果:"+b.add(0,8.9));//两个数相加结果:8.9
    }
}

以上代码运行结果均为可预见的。

你可能感兴趣的:(java,BigDecimal,基础篇)