在这里使用Python 2.7。
有人能解释为什么会在shell中发生这种情况吗?
>>> 5.2-5.0
0.20000000000000018
搜索产生了不同数量的数字但没有产生正确结果(非常小的数字和非常大的数字),但这似乎相当普遍,考虑到我使用的数字具有相同的比例,我不喜欢我认为这就是为什么会这样。
编辑:我想我没有定义“发生这件事”我的意思是它返回0.2 ... 018而不是简单地得到0.2。我得到了打印轮次,并删除了代码段中的打印部分,因为这会产生误导。
答案 0 :(得分: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)
是"0.2"
,而不是{{1 }}。但有时您需要获得所有精度,因此"0.20000000000000018"
- 即机器可读的再现 - 不会被截断,因此repr(f)
为repr(5.2-5.0)
。
现在唯一需要理解的是解释器shell的功能。正如Ashwini Chaudhary解释的那样,只是评估shell中的某些内容会打印出"0.20000000000000018"
,而repr
语句会打印出它的print
。
答案 1 :(得分:2)
shell使用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
答案 2 :(得分:1)
float.__str__
的默认实现仅将输出限制为12位数。
因此,最低有效数字被删除,剩下的数字是0.2。
要打印更多数字(如果有),请使用string formatting:
print '%f' % result # prints 0.200000
默认为6位数,但您可以指定更高的精度:
print '%.16f' % result # prints 0.2000000000000002
或者,python也提供了更新的string formatting method:
print '{0:.16f}'.format(result) # prints 0.2000000000000002
为什么python会产生不精确的'结果首先与floating point arithmetic的不精确性有关。如果您需要更可预测的精度,请使用decimal
module:
>>> from decimal import *
>>> getcontext().prec = 1
>>> Decimal(5.2) - Decimal(5.0)
Decimal('0.2')
答案 3 :(得分:0)
Python有两种不同的方法将对象转换为字符串,即__str__
和__repr__
方法。 __str__
是一个普通的字符串输出,由print
使用; __repr__
表示更准确的表示形式,是您不使用print
时或打印列表或词典内容时显示的内容。 __str__
舍入浮点值。
为什么减法的实际结果是0.20000000000000018而不是0.2精确,它与浮点的内部表示有关。完全代表5.2是不可能的,因为它是一个无限重复的二进制数。你最接近的是大约5.20000000000000018。