Python舍入错误

时间:2013-04-10 15:39:18

标签: python python-2.7

我只是使用python作为计算,我看到了这个

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 62 * 41.2 * 2 / 250
20.435200000000002
>>> 62 * 4.12 * 2 / 25
20.4352
>>>

为了确保我通过gcc解雇了以下代码,但这并未向我显示上述行为。我知道这可能是四舍五入的事情,但应该是统一的。为什么python在数学上加起来跟踪00000000002它不应该在那里。

C / C ++代码

#include <stdio.h>
int main () {
  printf ("%lf %lf \n", 62 * 41.2 * 2 / 250, 62 * 4.12 * 2 / 25);
}

结果

20.435200 20.435200

如果有人对特定数字感到好奇,他们属于某些引擎位移计算比较:)

5 个答案:

答案 0 :(得分:8)

除了@Ashwini Chaudhary回答,

问题:

为什么python在数学上加起来是00000000002它不应该在那里

答案:

因为机器中的值不是精确。这不是Python中的错误或代码中的错误。您将在支持二进制浮点运算的所有语言中看到完全相同的问题。但是,不同的语言可能会以不同的方式显示它(四舍五入)。

试试这个:

0.1 + 0.2

你会得到

0.30000000000000004

这是因为0.1不能完全以二进制形式表示。在基数2或二进制中,0.1是无穷重复数

0.0001100110011001100110011001100110011001100110011...

所以,Python决定改为关闭它。

我建议你阅读更多here

答案 1 :(得分:3)

在python中也使用print

In [87]: print 62 * 41.2 * 2 / 250
20.4352

In [88]: print 62 * 41.2 * 2 / 25
204.352

Python shell使用repr来显示输出,这就是为什么你得到那个奇怪的输出:

In [89]: print repr(62 * 41.2 * 2 / 250)
20.435200000000002

print使用str

In [90]: print str(62 * 41.2 * 2 / 250)
20.4352

答案 2 :(得分:3)

别担心,C实际上是这样做的,你只是因为显示的数字太少而不打印它:

#include <stdio.h>
int main () {
    printf ("%.16lf %.16lf \n", 62 * 41.2 * 2 / 250, 62 * 4.12 * 2 / 25);
}

给出

20.4352000000000018 20.4351999999999983

答案 3 :(得分:2)

尝试使用十进制

>>> from decimal import Decimal
>>> dec = Decimal('41.2')
>>> 62 * dec * 2 / 250
Decimal('20.4352')

请注意,您必须使用字符串作为参数。如果使用float作为参数,它将失败。

>>> dec1 = Decimal(41.2)
>>> dec2 = Decimal('41.2')
>>> dec1 == dec2
False
>>> print dec1, dec2
41.2000000000000028421709430404007434844970703125 41.2

答案 4 :(得分:0)

你正在接触使用二进制浮点数的常见怪事;这些是大多数计算机语言的共同点。输出的不同舍入策略可以隐藏这些问题,但它们仍然存在。理解这些的常用参考是"What Every Computer Scientist Should Know About Floating-Point Arithmetic",但在"Floating Point Arithmetic: Issues and Limitations"

还有一个Python特定指南

Python有几个解决方案可用于在需要时获得更精确的结果。第一个是decimal module,它使用十进制数而不是二进制数。

>>> from decimal import Decimal
>>> Decimal(62) * Decimal("41.2") * Decimal(2) / Decimal(250)
Decimal('20.4352')
>>> Decimal(62) * Decimal("4.12") * Decimal(2) / Decimal(25)
Decimal('20.4352')

还有fractions module跟踪单独的分子和分母,因此可以表示任何可能的分数。

>>> from fractions import Fraction
>>> Fraction("41.2")
Fraction(206, 5)
>>> Fraction(62) * Fraction("41.2") * Fraction(2) / Fraction(250)
Fraction(12772, 625)
>>> Fraction(62) * Fraction("4.12") * Fraction(2) / Fraction(25)
Fraction(12772, 625)
>>> float(Fraction(12772, 625))
20.4352