在Python 2和3中,float.__str__的行为不同吗?

5 浏览
0 Comments

在Python 2和3中,float.__str__的行为不同吗?

在Python 2.7中,floatrepr返回最接近的十进制数,精确到17位数字;这足以唯一地标识每个可能的IEEE浮点值。floatstr工作方式类似,只是将结果限制在12位数字以内;对于大多数情况来说,这是一个更合理的结果,并且可以让您免受二进制和十进制表示之间的轻微差异的影响。\nPython 2演示:http://ideone.com/OKJtxv\n

print str(1.4*1.5)
2.1
print repr(1.4*1.5)
2.0999999999999996

\n在Python 3.2中,strrepr似乎返回相同的结果。\nPython 3演示:http://ideone.com/oAKRsb\n

print(str(1.4*1.5))
2.0999999999999996
print(repr(1.4*1.5))
2.0999999999999996

\n有没有描述这种变化的PEP,或者其他负责人的声明?

0
0 Comments

Python 2和Python 3中的float.__str__行为不同的原因是由于Python 3.1引入了一种新的算法来表示浮点数的字符串repr,这个算法后来被移植到Python 2系列中,所以也出现在Python 2.7中。这个新算法使得在命令提示符下输入的“短”小数有相应的短表示。这消除了str和repr之间差异的一个现有原因,并使得可以为str和repr使用相同的算法。因此,在Python 3.2中,根据上面链接的讨论,str和repr被设为相同。这样做的原因是使语言更加简洁,清晰,并消除了在输出字符串时选择12位小数的任意性。除了简洁性外,还有一些不太明显的好处。过去,repr与str之间的区别对用户来说有些混淆的一方面是,repr会自动用于容器中。所以例如在Python 2.7中,以下代码会产生不一致的输出:

>>> x = 1.4 * 1.5
>>> print x
2.1
>>> print [x]
[2.0999999999999996]

然而,在Python 3.2中,我们得到了以下输出,这至少更加一致:

>>> x = 1.4 * 1.5
>>> print(x)
2.0999999999999996
>>> print([x])
[2.0999999999999996]

如果您确实想要隐藏不精确的数字,正确的方法仍然是使用字符串格式化来精确控制输出格式。例如:

>>> print("{:.12g}".format(x))
2.1

总之,这个变化有助于消除语言中的一些令人惊讶的地方。希望这解释了一些变化的原因。虽然我不会争辩说它在所有情况下都有益,正如你所指出的,旧的str具有隐藏不精确性的方便副作用。但是在我个人的观点中(当然,我是有偏见的),它确实有助于减少语言中的一些意外情况。

0