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

朱雀 2021-09-16 08:22 486阅读 0赞

【问题代码】:

  1. package demo;
  2. import java.math.BigDecimal;
  3. public class demo9 {
  4. public BigDecimal add(double value1,double value2){
  5. BigDecimal b1=new BigDecimal(value1);
  6. BigDecimal b2=new BigDecimal(value2);
  7. return b1.add(b2);
  8. }
  9. public static void main(String[] args) {
  10. demo9 b=new demo9();
  11. System.out.println("两个数相加结果:"+b.add(-1,8));//两个数相加结果:7
  12. System.out.println("两个数相加结果:"+b.add(-1.0,8.0));//两个数相加结果:7
  13. System.out.println("两个数相加结果:"+b.add(-1.5,8));//两个数相加结果:6.5
  14. System.out.println("两个数相加结果:"+b.add(-1.5,8.9));
  15. //两个数相加结果:7.4000000000000003552713678800500929355621337890625
  16. System.out.println("两个数相加结果:"+b.add(0,8.9));
  17. //两个数相加结果:8.9000000000000003552713678800500929355621337890625
  18. }
  19. }

【问题描述】:

在上面代码中我们可以看到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转化为字符串,就不会发生精确不准的情况了。

【代码修正】:

  1. package demo;
  2. import java.math.BigDecimal;
  3. public class demo10 {
  4. public BigDecimal add(double value1,double value2){
  5. BigDecimal b1=new BigDecimal(Double.toString(value1));
  6. BigDecimal b2=new BigDecimal(Double.toString(value2));
  7. return b1.add(b2);
  8. }
  9. public static void main(String[] args) {
  10. demo10 b=new demo10();
  11. System.out.println("两个数相加结果:"+b.add(-1,8));//两个数相加结果:7.0
  12. System.out.println("两个数相加结果:"+b.add(-1.0,8.0));//两个数相加结果:7.0
  13. System.out.println("两个数相加结果:"+b.add(-1.5,8));//两个数相加结果:6.5
  14. System.out.println("两个数相加结果:"+b.add(-1.5,8.9));//两个数相加结果:7.4
  15. System.out.println("两个数相加结果:"+b.add(0,8.9));//两个数相加结果:8.9
  16. }
  17. }

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

发表评论

表情:
评论列表 (有 0 条评论,486人围观)

还没有评论,来说两句吧...

相关阅读