我有点困惑,为什么 Python 在这种情况下会添加一些额外的小数数字,请帮忙解释一下。
>>> mylist = ["list item 1", 2, 3.14]
>>> print mylist ['list item 1', 2, 3.1400000000000001]
我有点困惑,为什么 Python 在这种情况下会添加一些额外的小数数字,请帮忙解释一下。
>>> mylist = ["list item 1", 2, 3.14]
>>> print mylist ['list item 1', 2, 3.1400000000000001]
浮点数是一种近似值,不能精确存储小数。由于它们试图在只有64位的情况下表示非常大范围的数字,所以它们必须在某种程度上进行逼近。
非常重要的一点是要意识到这一点,因为它会导致一些奇怪的副作用。例如,您可能非常合理地认为十个0.1
的总和应该是1.0
。虽然这看起来很合乎逻辑,但在浮点数的情况下也是错误的:
>>> f = 0.0
>>> for _ in range (10):
... f += 0.1
...
>>> print f == 1.0
False
>>> f
0.99999999999999989
>>> str(f)
1.0
你可能认为 n / m * m == n
。然而,在浮点数世界中,这并不正确。>>> (1.0 / 103.0) * 103.0
0.99999999999999989
或者同样奇怪的是,有人可能认为对于所有的n
,n + 1 != n
。 在浮点数领域,数字并不像这样工作:
>>> 10.0**200
9.9999999999999997e+199
>>> 10.0**200 == 10.0**200 + 1
True
# How much do we have to add to 10.0**200 before its
# floating point representation changes?
>>> 10.0**200 == 10.0**200 + 10.0**183
True
>>> 10.0**200 == 10.0**200 + 10.0**184
False
请参阅计算机科学家应该了解的浮点数知识,这是一个关于相关问题的绝佳概述。
如果您需要精确的十进制表示,请查看decimal模块,它是自2.4版本起成为Python标准库的一部分。它允许您指定有效数字的数量。缺点是,它比浮点数慢得多,因为浮点操作是由硬件实现的,而十进制操作纯粹是在软件中完成的。它也有自己的不准确性问题,但如果您需要精确表示十进制数(例如金融应用程序),那么它是理想的选择。
例如:
>>> 3.14
3.1400000000000001
>>> import decimal
>>> decimal.Decimal('3.14')
>>> print decimal.Decimal('3.14')
3.14
# change the precision:
>>> decimal.getcontext().prec = 6
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.142857')
>>> decimal.getcontext().prec = 28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1428571428571428571428571429')
当我尝试导入decimal模块时出现错误,我应该从哪里获取它?这可能听起来很愚蠢,但我是Python新手。 - user359925from decimal import * 追踪(最内层的): 文件“<交互式输入>”,第1行,位置? 导入错误:没有名为decimal的模块
Python 3.1 (r31:73572, Aug 15 2009, 17:12:41)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [3.14]
>>> print(a)
[3.14]
从Python 3.1的新特性文档中可以看到:
现在Python使用David Gay的算法来找到最短的浮点数表示,以避免一些困扰二进制浮点数的混淆。
这一点可以很容易地看出来,比如像1.1这样的数字在二进制浮点数中没有精确的等价物。由于没有精确的等价物,表达式
float('1.1')
会计算出最接近的可表示值,即十六进制下的0x1.199999999999ap+0
或者十进制下的1.100000000000000088817841970012523233890533447265625
。这个最接近的值被用于后续的浮点数计算。
如前所述,这一切都与浮点数是近似值有关。
如果您想要精确性,可以使用十进制数(它是一个精确的表示): http://docs.python.org/library/decimal.html
a = [1.5, 1.49999]
a
[1.5, 1.4999899999999999]
from decimal import Decimal
b = [1.5, Decimal('1.4999')]
b
[1.5, Decimal('1.4999')]
sin
、ln
和 sqrt
这样的函数在任何基数下都不返回精确答案。 - dan04我们可以通过这个命令来修复它:
>>> x = 1.2 - 1.0
>>> x
0.19999999999999996
>>> y = float(str(x))
>>> y
0.2
我添加了来自@mark的答案