繁体   English   中英

Python中出现意外的浮点表示

[英]Unexpected floating-point representations in Python

您好我在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 所有这些信息是如何产生的? 为什么它存储在那里,因为我的初始输入表示我不需要额外的信息,至少据我所知。

这已在Python 3.1中更改。 什么是新的页面:

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的情况,即使表示可能另有说明。

新算法依赖于底层浮点实现中的某些功能。 如果未找到所需的功能,将继续使用旧算法。 此外,文本pickle协议通过使用旧算法确保跨平台可移植性。

(供稿人:Eric Smith和Mark Dickinson; issue 1580

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

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

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

如果你使用一个数字 ,精确表示,如1.5 ,我猜走开的效果。

如果要在世界上任何一台机器上指定完全相同的小数,则必须使用decimal.Decimal。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM