我是靠谱客的博主 正直高跟鞋,最近开发中收集的这篇文章主要介绍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 在计算时精度丢失的问题

最后

以上就是正直高跟鞋为你收集整理的Java Double类精度丢失问题的全部内容,希望文章能够帮你解决Java Double类精度丢失问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(109)

评论列表共有 0 条评论

立即
投稿
返回
顶部