小编典典

Python中意外的浮点表示形式

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分别?所有这些信息是如何产生的?以及为什么将其存储在此处,因为我的初始输入表明我至少在我所知的范围内不需要这些额外的信息。


阅读 331

收藏
2021-01-20

共1个答案

小编典典

在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年

2021-01-20