python浮点数

我有点困惑为什么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 

或者也许同样奇怪,人们可能会认为对于所有的nn + 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 

请参阅每个计算机科学家应该了解的有关浮点数的问题,以便对这些问题进行精彩的总结。

如果您需要精确的十进制表示,请检查十进制模块,这是自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') 

值得注意的是,Python 3.1有一个新的浮点输出例程,它以预期的方式进行了四舍五入(它也被反向移植到Python 2.7中):

 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文档的新增function :

Python现在使用David Gay的algorithm来find不改变其值的最短浮点表示。 这应该有助于缓解一些围绕二进制浮点数的混淆。

用像1.1这样的数字很容易看出这个意义,它在二进制浮点上没有精确的等价物。 由于没有完全相同的expression式,所以像float('1.1')这样的expression式求值为hex的0x1.199999999999ap+0或十进制的0x1.199999999999ap+0的最接近的可表示值。 这个最接近的值在之后的浮点计算中仍然被使用。

如前所述,浮点是一个近似值。

如果你想精确,你可以使用一个十进制(这是一个精确的表示): 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')] 

我们可以通过这个命令来修复它:

 >>> x = 1.2 - 1.0 >>> x 0.19999999999999996 >>> y = float(str(x)) >>> y 0.2 

我从@mark添加了一个答案