Java 双减法精度问题
我的同事做了这个实验:Java 双减法精度问题,java,double,Java,Double,我的同事做了这个实验: public class DoubleDemo { public static void main(String[] args) { double a = 1.435; double b = 1.43; double c = a - b; System.out.println(c); } } 对于这个一级操作,我期望得到以下输出: 0.005 但出乎意料
public class DoubleDemo {
public static void main(String[] args) {
double a = 1.435;
double b = 1.43;
double c = a - b;
System.out.println(c);
}
}
对于这个一级操作,我期望得到以下输出:
0.005
但出乎意料的是,结果是:
0.0050000000000001155
为什么double在这么简单的操作中失败了?如果double不是这项工作的数据类型,我应该使用什么呢?double和float不完全是实数 在任何范围内都有无穷多的实数,但表示它们的位数是有限的因此,双精度浮点和浮点的舍入误差是预期的 您得到的数字是最接近的数字,在浮点表示法中可以用double表示 有关更多详细信息,请阅读[警告:可能是高级别的]
您可能希望使用获取精确的十进制数[但当您尝试获取
1/3
]时,您将再次遇到舍入错误。double
在内部以二进制小数形式存储,如1/4+1/8+1/16+…
值0.005
——或值1.435
——不能存储为二进制的精确分数,因此double
不能存储精确值0.005
,减去的值也不太精确
如果您关心精确的十进制算法,请使用BigDecimal
你也可以找到有用的阅读资料。
double
和float
算法永远不会完全正确,因为“在引擎盖下”会发生舍入
从本质上讲,double和float可以有无限数量的小数,但在内存中,它们必须由一些实数位数表示。所以,当你做这个十进制算术时,会发生一个舍入过程,如果你把所有的小数都考虑进去,舍入过程通常会减少一个非常小的数值
如前所述,如果您需要完全精确的值,则使用以不同方式存储其值的
BigDecimal
是的,它使用BigDecimal操作以这种方式工作
private static void subtractUsingBigDecimalOperation(double a, double b) {
BigDecimal c = BigDecimal.valueOf(a).subtract(BigDecimal.valueOf(b));
System.out.println(c);
}
输出:
使用double时2.15和1.0之间的差异为:1.0499999998
2.15和1.0之间使用BigDecentral的区别是:1.05感谢分享您的实验+1可能的重复并不能回答这个问题。嗯,你是对的。试着做一些关于BigDecimal的小例子。已经有人在回答这个问题了。不需要重复。因此,答案是为了提供一个完整的、自包含的答案。如果你觉得另一个答案遗漏了什么,在你有足够的声誉后留下评论。如果你认为你能写出一个更好的完整答案,那就这么做吧。不要发布像这样的“半答案”。这不好,因为它只是设置值,不适用于负值。说它们“永远”不会完全正确是不准确的。正确的说法是,除了分母不是二的幂的分数之外,它们永远不会完全正确。我有一个问题,如果我们有一个double,我们在做算术运算之前把它转换成BigDecimal,它会工作吗?不过我要检查一下自己:)@muasif80:不,不会的。如果你想做精确的算术,千万不要碰一个
双精度的。好的,谢谢。我尝试了下面分享的一个例子。但我会尽量听从你的建议,“分数之和”这个概念从何而来?你通常有指数和尾数,因此表示的值是V=(2^e)*(1.m)@Jack:是的。你认为m
是什么?BigDecimal.valueOf
对一些double
值有效,但不是全部。Ok。我必须首先检查double值是如何出现的,然后是在我的特殊情况下。我将根据你的见解改变这一点。谢谢你的回复。
private static void subtractUsingBigDecimalOperation(double a, double b) {
BigDecimal c = BigDecimal.valueOf(a).subtract(BigDecimal.valueOf(b));
System.out.println(c);
}
public class BigDecimalExample {
public static void main(String args[]) throws IOException {
//floating point calculation
double amount1 = 2.15;
double amount2 = 1.10;
System.out.println("difference between 2.15 and 1.0 using double is: " + (amount1 - amount2));
//Use BigDecimal for financial calculation
BigDecimal amount3 = new BigDecimal("2.15");
BigDecimal amount4 = new BigDecimal("1.10") ;
System.out.println("difference between 2.15 and 1.0 using BigDecimal is: " + (amount3.subtract(amount4)));
}
}