Java Double类精度丢失问题

一、精度丢失原理

例1:15.75 -> 1111.11

step1:拆分

将整数和小数部分拆分得:15 和 0.75

step2:计算整数部分

整数部分是 15,计算得 1111,见下图:

在这里插入图片描述

step3:计算小数部分

小数部分是 0.75,计算得 0.11,见下图:

Java 中 double 在计算时精度丢失的问题

step4:合并

将整数部分和小数部分拼接得到最终的结果:1111.11

复原:1111.11 -> 15.75

step1:拆分

将整数和小数部分拆分得:1111 和 0.11

step2:计算整数部分

整数部分 1111 计算得 15,详细计算过程见下图:

Java 中 double 在计算时精度丢失的问题

step3:计算小数部分

小数部分 0.11 计算得 0.75,详细计算过程见下图

在这里插入图片描述

step4:合并

整数部分和小数部分合并得最终的结果:15.75

例2:0.1 -> 0.000110011001100110011001100…………

step1:拆分

将整数部分和小数部分拆分得: 0 和 0.1

step2:计算整数部分

整数部分是 0 ,计算得: 0

step3:计算小数部分

小数部分是 0.1,计算得:0.0001100110011001100………….,计算过程见下图:

在这里插入图片描述

step4:合并

二、解决方法

//double参数构造函数
public BigDecimal(double val) {
        this(val,MathContext.UNLIMITED);
    }

//String参数构造函数
public BigDecimal(String val) {
        this(val.toCharArray(), 0, val.length());
    }

//静态方法(实际上是对方法二的封装)
public static BigDecimal valueOf(double val) {
        // Reminder: a zero double returns '0.0', so we cannot fastpath
        // to use the constant ZERO.  This might be important enough to
        // justify a factory approach, a cache, or a few private
        // constants, later.
        return new BigDecimal(Double.toString(val));
    }

Demo:

double d1 = 0.1, d2 = 0.2;
System.out.println(d1 + d2);
System.out.println(new BigDecimal(d1).add(new BigDecimal(d2)).doubleValue());
System.out.println(BigDecimal.valueOf(d1).add(BigDecimal.valueOf(d2)).doubleValue());
System.out.println(new BigDecimal(Double.toString(d1)).add(new         
           BigDecimal(Double.toString(d2))).doubleValue());


//result
0.30000000000000004
0.30000000000000004
0.3
0.3

不能使用BigDecimal.valueOf(0.1+0.2)的方式,因为这本质上还是没有避免双浮点数的运算。

转载链接:Java 中 double 在计算时精度丢失的问题

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值