Mar*_*som 23 python python-2.7 python-3.x floating-point-conversion
在Python 2.7中,repr
a float
返回最接近17位数的最接近的十进制数; 这足够精确,可以唯一地标识每个可能的IEEE浮点值.str
一个float
类似的工作,除了它将结果限制为12位数; 对于大多数用途,这是一个更合理的结果,并使您免受二进制和十进制表示之间的细微差别.
Python 2演示:http://ideone.com/OKJtxv
print str(1.4*1.5)
2.1
print repr(1.4*1.5)
2.0999999999999996
Run Code Online (Sandbox Code Playgroud)
在Python 3.2中它出现str
并repr
返回相同的东西.
Python 3演示:http://ideone.com/oAKRsb
print(str(1.4*1.5))
2.0999999999999996
print(repr(1.4*1.5))
2.0999999999999996
Run Code Online (Sandbox Code Playgroud)
是否存在描述变更的PEP或负责人的其他声明?
Mar*_*son 33
不,没有PEP.错误跟踪器中存在一个问题,以及Python开发人员邮件列表上的相关讨论.虽然我负责提出和实施变更,但我不能说这是我的想法:它是在与Guido在EuroPython 2010上的对话中产生的.
更多细节:正如在评论中已经提到的,Python 3.1为repr
float 的字符串引入了一种新算法(后来反向移植到Python 2系列,因此它也出现在Python 2.7中).作为这种新算法的结果,在提示符处键入的"短"十进制数具有相应的短表示.这消除之间的差额现有的原因之一str
,并repr
,并有可能使用相同的算法都str
和repr
.因此对于Python 3.2,遵循与上面相关的讨论,str
并repr
使其相同.至于为什么:它使语言变得更小更清洁,并且在输出字符串时它删除了相当任意的12位数选择.(repr
在2.7之前的Python版本中使用的17位数的选择远非任意,顺便说一下:当转换为带有17位有效数字的十进制时,两个不同的IEEE 754 binary64浮点数将具有不同的表示形式,17是具有17位有效数字的最小整数这个性质.)
除了简单之外,还有一些不太明显的好处.过去让用户感到困惑的repr
对比str
区别的一个方面是repr
自动在容器中使用的事实.例如在Python 2.7中:
>>> x = 1.4 * 1.5
>>> print x
2.1
>>> print [x]
[2.0999999999999996]
Run Code Online (Sandbox Code Playgroud)
我确定至少有一个StackOverflow问题在某个地方询问这个现象:这是一个这样的,另一个是最近的一个.通过Python 3.2中引入的简化,我们得到了这个:
>>> x = 1.4 * 1.5
>>> print(x)
2.0999999999999996
>>> print([x])
[2.0999999999999996]
Run Code Online (Sandbox Code Playgroud)
至少更一致.
如果您确实希望能够隐藏不精确,那么正确的方法仍然是相同的:使用字符串格式来精确控制输出格式.
>>> print("{:.12g}".format(x))
2.1
Run Code Online (Sandbox Code Playgroud)
我希望这解释了改变背后的一些推理.我不打算认为这是普遍有益的:正如你所指出的那样,老人str
有隐藏不精确的方便副作用.但在我看来(当然,我有偏见),它确实有助于从语言中消除一些惊喜.