为什么这个减法不等于零?
我在ColdFusion代码中遇到了这些值,但Google计算器似乎有相同的“错误”,其中差异不为零。
416582.2850 – 411476.8100 – 5105.475 = -2.36468622461E-011
http://www.google.com/search?hl=en&rlz=1C1GGLS_enUS340US340&q=416582.2850+-+411476.8100+-+5105.475&aq=f&oq=&aqi=
JavaCast将这些设置为long / float / double没有帮助 – 它会导致其他非零差异。
这是因为在基数10中“看起来”圆的十进制数在基数2中不能完全表示(这是计算机用来表示浮点数的数字)。 有关此问题和解决方法的详细说明,请参阅文章科学家应该知道的关于浮点运算的文章。
浮点不准确(有无限数量的实数,只有有限数量的32位或64位数字来表示它们)。
如果您无法处理微小错误,则应使用BigDecimal
。
在ColdFusion中使用PrecisionEvaluate()
(它将在Java中使用BigDecimal
)
zero = PrecisionEvaluate(416582.2850 - 411476.8100 - 5105.475);
与Evaulate()
不同,不需要“”。
由于计算机以二进制forms存储数字,因此浮点数不精确。 1E-11是由于将这些十进制数舍入到最接近的可表示二进制数而产生的微小差异。
这个“bug”不是bug。 这是浮点运算的工作原理。 请参阅: http : //docs.sun.com/source/806-3568/ncg_goldberg.html
如果您想在Java中使用任意精度,请使用BigDecimal
:
BigDecimal a = new BigDecimal("416582.2850"); BigDecimal b = new BigDecimal("411476.8100"); BigDecimal c = new BigDecimal("5105.475"); System.out.println(a.subtract(b).subtract(c)); // 0.0
问题是浮点类型的不精确表示。 因为这些不能精确地表示为浮点数,所以会得到一些精度损失,导致操作的错误很小。 通常使用浮点数来比较结果是否等于某个小epislon中的另一个值(误差因子)。
这些是浮点问题,使用BigDecimal
会修复它。
更改减法的顺序在Google中也会产生零。
416582.2850 - 5105.475 - 411476.8100 = 0