Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么这个减法不等于零?_Java_Math_Coldfusion_Floating Point - Fatal编程技术网

Java 为什么这个减法不等于零?

Java 为什么这个减法不等于零?,java,math,coldfusion,floating-point,Java,Math,Coldfusion,Floating Point,我在我的ColdFusion代码中偶然发现了这些值,但是Google计算器似乎有相同的“bug”,其中差异不是零 416582.2850-411476.8100-5105.475=-2.36468622461E-011 JavaCast’s to long/float/double没有帮助——它会导致其他非零差异。浮点不准确(实数的数量是无限的,用32位或64位数字来表示它们的数量是有限的) 如果你不能处理微小的错误,你应该改为使用。这是因为以10为基数“看”四舍五入的十进制数字在以2为基数(

我在我的ColdFusion代码中偶然发现了这些值,但是Google计算器似乎有相同的“bug”,其中差异不是零

416582.2850-411476.8100-5105.475=-2.36468622461E-011


JavaCast’s to long/float/double没有帮助——它会导致其他非零差异。

浮点不准确(实数的数量是无限的,用32位或64位数字来表示它们的数量是有限的)


如果你不能处理微小的错误,你应该改为使用。

这是因为以10为基数“看”四舍五入的十进制数字在以2为基数(计算机用来表示浮点数)时不能准确表示。有关此问题和解决方法的详细说明,请参阅本文。

问题在于浮点类型的不精确表示。因为这些不能精确地表示为浮点数,所以会导致精度损失,从而导致操作产生小错误。通常,对于浮点数,您需要比较结果是否等于某个小的epilon(错误因子)中的另一个值。

由于计算机以二进制形式存储数字,浮点数是不精确的。1E-11是一个微小的差异,因为将这些十进制数四舍五入到最接近的可表示二进制数。

此“错误”不是错误。这就是浮点运算的工作原理。见:

如果您想要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

这些都是浮点问题,使用
BigDecimal
可以解决它

在谷歌,改变减法的顺序也会得到零

416582.2850 - 5105.475 - 411476.8100 = 0

在ColdFusion中使用
PrecisionEvaluate()
(在Java中使用
BigDecimal


Evaulate()
不同,不需要使用“”。

在SO上创建帐户时,应该有一个浮点测验。我想这是网站上最常问的问题。@recursive:当我学习编程时,在第一次讨论浮点时就提到了浮点数的精度不足,此后也多次提到。他们不再这样做了吗?哈,哈斯凯尔也有同样的错误,而且它通常很擅长这些事情:前奏曲>416582.2850-411476.8100-5105.475-2.3646862246096134e-11-2.36468622461E-011?在我的社区,他回答“零”。但是416582.2850-411476.8100可以精确地表示为5105.475。这些数字只有4位小数,不重复。4位小数太精确了吗?不是以10为基数的表示必须是有限的,而是以2为基数的表示。关于哪些分数可以用二进制表示的解释,请参见(只有那些分母的素数因子是2的分数)。@Brian:这不是小数的数目。分数1/3不能用基数10表示,对吗?这将是3.3333333。二进制(基数2)中的小数(或分数)也是如此。1.1虽然在10进制中有效,但不能在2进制中准确表示,因此会导致所谓的“舍入误差”。5105.475是一个不能用双精度表示的数字。PrecisionEvaluate是我需要的ColdFusion函数。实际上,这些数字都不能精确地表示为双精度值。+1非常好的参考资料,也请查看G.L.Steel的“如何准确打印浮点数字”。我今天早上读了这一段,我发誓:“如果我能回到过去,改变一件事,我可能会尝试让一些早期的迭代前的人感兴趣,在他们计数时不使用拇指。它本可以成为标准,在现代,它会让很多事情变得更容易。另一方面,我们从十进制与二次幂不相容的斗争中学到了很多。”-盖伊·斯蒂尔,工作中的编码员虽然八进制可能对计算机很方便,但我建议如果我们每只手上都有六个手指(12进制)那么我们的数字系统总体上会更好。12比10有更多的小因素。
zero = PrecisionEvaluate(416582.2850 - 411476.8100 - 5105.475);