【问题代码】:
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
}
}
以上代码运行结果均为可预见的。