Python中出现意外的浮点表示

时间:2012-06-28 09:50:56

标签: python dictionary hashtable

您好我在Python中使用字典存储一些城市及其人口:

population = { 'Shanghai' : 17.8, 'Istanbul' : 13.3, 'Karachi' : 13.0, 'mumbai' : 12.5 }

现在,如果我使用命令print population,我会得到结果:

{'Karachi': 13.0, 'Shanghai': 17.800000000000001, 'Istanbul': 13.300000000000001, 'mumbai': 12.5}

如果我使用命令print population['Shanghai'],我会得到17.8的初始输入。

我的问题是17.813.3分别如何变成17.80000000000000113.300000000000001?所有这些信息是如何产生的?为什么它存储在那里,因为我的初始输入表明我不需要额外的信息,至少据我所知。

3 个答案:

答案 0 :(得分:5)

这在Python 3.1中已经改变。来自what's new页面:

  

Python现在使用David Gay的算法来找到最短的算法   不改变其值的浮点表示。这个   应该有助于缓解围绕二进制浮动的一些混乱   点数。

     

很容易看到像1.1那样的重要性   在二进制浮点中没有精确的等价物。既然有   没有确切的等价物,像float('1.1')这样的表达式求值   最接近的可表示值,以十六进制表示0x1.199999999999ap+0   或十进制1.100000000000000088817841970012523233890533447265625。   最接近的值仍在后续浮点中使用   计算

     

新功能是如何显示数字。以前,Python使用了   简单的方法。 repr(1.1)的值计算为format(1.1, '.17g'),评估为'1.1000000000000001'。的优点   使用17位数是因为它依靠IEEE-754保证来确保   eval(repr(1.1))将完全往返到其原始值。   缺点是许多人发现输出混乱   (误认为二进制浮点的内在局限性   表示为Python本身的问题。)

     

repr(1.1)的新算法更智能,并返回'1.1'。   实际上,它搜索所有等效的字符串表示(一个   使用相同的底层浮点值存储并返回   最短的代表性。

     

新算法在可能的情况下倾向于发出更清晰的表示,   但它并没有改变潜在的价值观。所以,情况仍然如此   即使表达可能暗示1.1 + 2.2 != 3.3 {{1}}   否则。

     

新算法取决于底层的某些功能   浮点实现。如果找不到所需的功能,   将继续使用旧算法。此外,文字泡菜   协议通过使用旧协议确保跨平台可移植性   算法

     

(由Eric Smith和Mark Dickinson提供; issue 1580

答案 1 :(得分:2)

您需要了解浮点数在计算机中的工作方式。

基本上,并非所有十进制数都可以准确存储,在这种情况下,您将得到最接近的数字。有时这种抽象会泄漏,你会看到错误。

这可能是由于您描述的两个用例的打印逻辑存在差异。我无法重新生成行为(在Win64中使用Python 2.7.2)。

如果您使用 可以准确表示的数字,例如1.5,我会猜测效果会消失。

答案 2 :(得分:1)

如果你想要在世界上任何一台机器上指定十进制数,那么你必须使用decimal.Decimal。

有关信息,请参阅Python手册:http://docs.python.org/library/decimal.html

>>> from decimal import Decimal
>>> print Decimal('3.14')
3.14