这是Java中的故障吗?
我去解决这个表达式:3.1 - 7.1
我得到答案:-3.9999999999999996
这里发生了什么?
可以在这里找到一个很好的解释。http://www.ibm.com/developerworks/java/library/j-jtp0114/
浮点运算很少是精确的。虽然某些数字(例如 0.5)可以精确地表示为二进制(以 2 为底)十进制(因为 0.5 等于 2-1),但其他数字(例如 0.1)则不能。因此,浮点运算可能会导致舍入错误,从而产生接近 - 但不等于 - 您可能期望的结果。例如,下面的简单计算得出 2.600000000000001,而不是 2.6:
double s=0; for (int i=0; i<26; i++) s += 0.1; System.out.println(s);
类似地,将 .1*26 相乘产生的结果与将 .1 自身相加 26 次的结果不同。当从浮点转换为整数时,舍入错误变得更加严重,因为转换为整数类型会丢弃非整数部分,即使对于“看起来”它们应该具有整数值的计算也是如此。例如,以下语句:
double d = 29.0 * 0.01; System.out.println(d); System.out.println((int) (d * 100));
将产生输出:
0.29 28
这可能不是您一开始所期望的。
有关详细信息,请参阅提供的参考。
double
正如其他几个人所提到的,如果您想获得一个精确的十进制值,例如在实施货币应用程序时,您无法指望。你应该做的是仔细看看BigDecimal:
BigDecimal a = new BigDecimal("3.1");
BigDecimal b = new BigDecimal("7.1");
BigDecimal result = a.subtract(b);
System.out.println(result); // Prints -4.0
计算机是 100% 的,所以在数学世界中是正确的,但对普通人来说却不是。Java 不能在特定数字上出现错误,因为它只是以相同方式运行但输入不同的代码!
PS谷歌如何四舍五入
浮点数舍入误差
同样的方式3 * 0.1 != 0.3
(至少当它没有被编译器折叠时)
自动类型提升正在发生,这就是结果。
这里有一些资源可以学习。
http://docs.oracle.com/javase/specs/jls/se5.0/html/conversions.html
下一步是学习使用格式化程序将其格式化为给定的精度/要求。