如果您将以下内容放入App Engine Shell,则会获得'50.49'
。这个结果在2.5和2.7运行时都是一致的。
>> a = '%0.2f' % (round(float(u'50.485'), 2),)
>> a
'50.49'
但是,如果我将相同的东西放入运行python 2.7.1的本地MacBook Pro中,我会得到'50.48'
。
>> a = '%0.2f' % (round(float(u'50.485'), 2),)
>> a
'50.48'
为什么会有所不同,如何在本地计算机和App Engine的服务器之间保持一致?
答案 0 :(得分:4)
显然,Google App Engine使用“float”C类型(IEEE 754单精度),而本地Python使用“double”代替(IEEE 754双精度)。
我怀疑CPython有一个配置开关使用'float'而不是'double',但是没有找到。
答案 1 :(得分:2)
有趣的是,这个确切的主题在官方Python教程中有所介绍。
浮点算术:问题和限制
http://docs.python.org/2/tutorial/floatingpoint.html
其他惊喜也来自这个。例如,如果您尝试舍入 值2.675到两位小数,你得到这个
>>> >>> round(2.675, 2) 2.67
内置round()函数的文档说明了它 舍入到最接近的值,从零开始四舍五入。自从 小数分数2.675正好在2.67和2.68之间,你 可能期望这里的结果是(二进制近似)2.68。 它不是,因为当十进制字符串2.675转换为a时 二进制浮点数,它再次被二进制替换 近似,其精确值为
2.67499999999999982236431605997495353221893310546875
由于这个近似值略微接近2.67而不是2.68,因此 四舍五入。
如果你处在一个你关心小数点的情况 中途案例是四舍五入的,你应该考虑使用小数 模块。顺便提一下,十进制模块也提供了一个很好的方法 “看到”存储在任何特定Python float中的确切值
>>> >>> from decimal import Decimal >>> Decimal(2.675) Decimal('2.67499999999999982236431605997495353221893310546875')
尽管使用FORTRAN,但官方Python教程(http://www.lahey.com/float.htm)中链接的文章之一正确地描述了IEEE 754的真正含义:
不同的计算机使用不同的位数来存储 浮点数字。 即使使用相同的IEEE格式 存储数字,因为计算的差异可能会发生 中间寄存器的大小。增加可移植性并确保 一致的结果,我建议不要比较确切的平等 FORTRAN中的实数。
因此,如果你真的关心这一点,那么一定要使用内置的十进制模块(或者cdecimal模块,这里有http://pypi.python.org/pypi/cdecimal/2.3,如果性能有问题的话)。
答案 2 :(得分:0)
其他答案是正确的,所以我不会就round
函数的行为发表任何意见,但如果你想获得一致的结果,可以跳过round
,因为你正在使用您在示例中显示的字符串格式('%0.2f'
)。
>> a = '%0.2f' % (float(u'50.485'))
>> a
'50.48'