2009-10-20 89 views
3
x = 4.2 - 0.1 

vb.net给4.1000000000000005
蟒蛇给4.1000000000000005为什么简单的浮点算术运算会返回VB.Net和Python中意外(不准确)的结果?

Excel中给出了4.1
Google calc4.1

这是什么情况的原因是什么?

+2

Google calc explicity将输入转换为浮点数,然后截断精度问题。请参阅http://en.wikipedia.org/wiki/Floating_point#Minimizing_the_effect_of_accuracy_problems。 – 2009-10-20 14:30:43

+7

请阅读三次或四次:http://docs.sun.com/source/806-3568/ncg_goldberg.html – nlucaroni 2009-10-20 14:31:09

+3

重复。 http://stackoverflow.com/questions/1089018/why-cant-decimal-numbers-be-represented-exactly-in-binary,http://stackoverflow.com/questions/177506/why-do-i-see- a-double-variable-initialized-some-value-like-21-4-as-21-39999961,http://stackoverflow.com/questions/963873/1-265-10000-126499-99999999999等 – 2009-10-20 14:54:20

回答

13

Float/double precision.

你必须记住,在二进制,4.1 = 4 + 1/10。 1/10是二进制的无限重复和,很像1/9是十进制的无限和。

+0

0.000110011001100 ...二进制数是0.1的十进制数。 http://www.exploringbinary.com/binary-converter/ – 2009-10-20 15:24:42

4

真的没有问题。这只是漂浮工作的方式(他们的内部二进制表示)。总之:

>>> from decimal import Decimal 
>>> Decimal('4.2')-Decimal('0.1') 
Decimal('4.1') 
+0

+1解决方法。 – 2009-10-20 14:33:30

1

在vb.net中,您可以通过使用十进制类型,而不是避免这个问题:

Dim x As Decimal = 4.2D - 0.1D 

结果是4.1。

10
>>> x = 4.2 - 0.1 
>>> x 
4.1000000000000005 

>>>>print(x) 
4.1 

这是因为how numbers are stored internally

计算机用二进制表示数字,而不是十进制数,就像我们人类习惯的那样。使用浮点数时,计算机必须将近似为以达到最接近的二进制浮点值。

Almost all machines today(2000年11月)使用IEEE-754浮点运算,几乎所有平台都将Python映射到IEEE-754“双精度”映射。 754双精度包含53位精度,因此在输入时,计算机会努力将0.1转换为最接近的分数,它可以是J/2***N*,其中J是一个包含正好53位的整数。

如果print数量it will show the approximation,截断为正常值。例如,实数0.10.1000000000000000055511151231257827021181583404541015625

如果你真的需要基于十进制数(如果你不知道这个问题的答案,你不),您可以使用(在Python)decimal.Decimal

>>> from decimal import Decimal 
>>> Decimal("4.2") - Decimal("0.1") 
Decimal("4.1") 

二进制浮点算法有很多这样的惊喜。 “0.1”的问题在下面的“Representation Error”部分详细解释。 请参阅The Perils of Floating Point了解其他常见惊喜的更完整说明。

就像接近尾声说的那样,“没有简单的答案。”但是,不要过分警惕浮点!Python浮点运算中的错误是从浮点硬件继承而来的,并且在大多数机器上,每个操作的执行次数不会超过1个部分,即2**53。这对于大多数任务来说已经足够了,但是您需要记住它不是十进制算术,并且每个浮点操作都会遇到新的舍入错误。

虽然存在病态情况,但对于大多数临时使用的浮点运算,如果您只是将最终结果显示为您期望的小数位数,您会最终看到预期的结果。 str()通常就足够了,而为了更好地控制,请参阅Format String Syntaxstr.format()方法的格式说明符。

+1

1.1的实际值是0.1000000000000000055511151231257827021181583404541015625。 =>关闭1.0 – foosion 2009-10-20 15:22:19

+0

@foosion:良好的捕获。 – voyager 2009-10-20 15:30:30

相关问题