概述
一、精度丢失原理
例1:15.75 -> 1111.11
step1:拆分
将整数和小数部分拆分得:15 和 0.75
step2:计算整数部分
整数部分是 15,计算得 1111,见下图:
step3:计算小数部分
小数部分是 0.75,计算得 0.11,见下图:
step4:合并
将整数部分和小数部分拼接得到最终的结果:1111.11
复原:1111.11 -> 15.75
step1:拆分
将整数和小数部分拆分得:1111 和 0.11
step2:计算整数部分
整数部分 1111 计算得 15,详细计算过程见下图:
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类精度丢失问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复