4

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

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

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

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

而如果我使用命令print population['Shanghai'],我会得到17.8.

17.8我对你的问题是 the和 the是如何分别13.3变成17.800000000000001and的13.300000000000001?所有这些信息是如何产生的?以及为什么将其存储在那里,因为我的初始输入表明我不需要那些额外的信息,至少据我所知。

4

3 回答 3

6

这在 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 供稿;第 1580 期

于 2012-06-28T10:04:45.747 回答
2

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

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

这可能是由于用于您描述的两个用例的打印逻辑不同。我无法重现该行为(在 Win64 中使用 Python 2.7.2)。

如果您使用一个完全可表示的数字例如1.5,我猜效果会消失。

于 2012-06-28T09:53:29.433 回答
1

如果您想让小数点完全按照您在世界上任何机器上指定的方式表示,则必须使用 decimal.Decimal。

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

>>> from decimal import Decimal
>>> print Decimal('3.14')
3.14
于 2012-06-28T10:01:57.167 回答