2

可能重复:
浮点限制

在这里使用 Python 2.7。

有人可以解释为什么会在 shell 中发生这种情况吗?

>>> 5.2-5.0
0.20000000000000018

搜索产生了关于不同比例的数字没有产生正确结果的东西(一个非常小的数字和一个非常大的数字),但这似乎很笼统,考虑到我使用的数字是相同的比例,我不认为这就是为什么会发生这种情况。

编辑:我想我没有定义“发生的事情”我的意思是它返回 0.2 ... 018 而不是简单地导致 0.2。我得到了打印轮次,并删除了代码片段中的打印部分,因为这具有误导性。

4

4 回答 4

5

您需要了解 5.2-5.0 确实是 0.20000000000000018,而不是 0.2。对此的标准解释可在What Every Computer Scientist Should Know About Floating-Point Arithmetic中找到。

如果您不想阅读所有这些内容,只需接受 5.2、5.0 和 0.20000000000000018 都只是近似值,只要计算机可以接近您真正采用的数字即可。

Python 有一些技巧可以让你不知道每个计算机科学家都应该知道什么,但仍然可以侥幸逃脱。主要技巧是str(f)——也就是说,浮点数的人类可读格式——被截断为 12 位有效数字,因此str(5.2-5.0)is "0.2", not "0.20000000000000018"。但有时你需要你能得到的所有精度,所以repr(f)——即机器可读的再现——不会被截断repr(5.2-5.0)"0.20000000000000018".

现在唯一需要了解的是解释器 shell 的作用。正如 Ashwini Chaudhary 解释的那样,仅评估 shell 中的某些内容会打印出它的repr,而print语句会打印出它的str.

于 2012-09-25T22:06:05.647 回答
2

外壳使用repr()

In [1]: print repr(5.2-5.0)
0.20000000000000018

In [2]: print str(5.2-5.0)
0.2

In [3]: print 5.2-5.0
0.2
于 2012-09-25T21:59:57.680 回答
1

的默认实现float.__str__仅将输出限制为 12 位。

因此,最低有效数字被删除,剩下的是值 0.2。

要打印更多数字(如果可用),请使用字符串格式

print '%f' % result  # prints 0.200000

默认为 6 位,但您可以指定更高的精度:

print '%.16f' % result  # prints 0.2000000000000002

或者,python 也提供了一种更新的字符串格式化方法

print '{0:.16f}'.format(result)  # prints 0.2000000000000002

为什么python首先产生“不精确”的结果与浮点运算的不精确性质有关。如果您需要更可预测的精度,请改用该decimal模块:

>>> from decimal import *
>>> getcontext().prec = 1
>>> Decimal(5.2) - Decimal(5.0)
Decimal('0.2')
于 2012-09-25T21:58:51.837 回答
0

Python 有两种将对象转换为字符串的方法,即__str____repr__方法。__str__是一个正常的字符串输出,由print;使用 __repr__旨在提供更准确的表示,并且是在您不使用时显示print的内容,或者当您打印列表或字典的内容时。 __str__舍入浮点值。

至于为什么减法的实际结果是0.20000000000000018而不是0.2,这与浮点的内部表示有关。不可能准确地表示 5.2,因为它是一个无限重复的二进制数。您可以到达的最接近的大约是 5.20000000000000018。

于 2012-09-25T22:04:13.940 回答