Why don't I get zero when I subtract the same floating point number from itself in Perl?
本问题已经有最佳答案,请猛点这里访问。
Possible Duplicates:
Why is floating point arithmetic in C# imprecise?
Why does ghci say that 1.1 + 1.1 + 1.1 > 3.3 is True?
1 2 3 4 5 6 7 8 | #!/usr/bin/perl $l1 ="0+0.590580+0.583742+0.579787+0.564928+0.504538+0.459805+0.433273+0.384211+0.3035810"; $l2 ="0+0.590580+0.583742+0.579788+0.564928+0.504538+0.459805+0.433272+0.384211+0.3035810"; $val1 = eval ($l1); $val2 = eval ($l2); $diff = (($val1 - $val2)/$val1)*100; print" (($val1 - $val2)/$val1)*100 ==> $diff "; |
令人惊讶的是,最终的产出是
1 | ((4.404445 - 4.404445)/4.404445)*100 ==> -2.01655014354845e-14. |
它不应该是零吗?????请任何人解释一下……
每一个计算机科学家都应该知道什么是浮点运算
明白为什么C中的浮点运算不精确吗?
这与Perl无关,但与浮点相关。
它非常接近于零,这是我所期望的。
为什么应该是零?0.579787!=0.579788和0.433273!= 0.433272。很可能这些都没有一个精确的浮点表示,所以您应该期待一些不准确的地方。
从Perlfaq4的答案到为什么我会得到长小数(如19.94999999999),而不是我应该得到的数字(如19.95)?:
在内部,您的计算机以二进制表示浮点数字。数字计算机(如二次乘方)不能准确地存储所有的数字。有些实数在这个过程中会失去精度。这是计算机如何存储数字和影响所有计算机语言的问题,而不仅仅是Perl。
PerlNumber显示数字表示和转换的详细信息。
要限制数字中的小数位数,可以使用printf或sprintf函数。有关详细信息,请参阅"浮点运算"。
当您将两个字符串更改为相等时(
它所证明的是,您可以创建两个不同的浮点数(
Vinko Vrsalovic发布了一些很好的链接来解释原因。