我是靠谱客的博主 正直高跟鞋,这篇文章主要介绍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:合并

二、解决方法

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//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:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部