use*_*925 10 python floating-point numerical floating-accuracy
我有点困惑为什么python在这种情况下添加一些额外的十进制数,请帮忙解释一下
>>> mylist = ["list item 1", 2, 3.14]
>>> print mylist ['list item 1', 2, 3.1400000000000001]
Run Code Online (Sandbox Code Playgroud)
fma*_*ark 14
浮点数是近似值,它们不能精确地存储十进制数.因为它们试图仅以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
Run Code Online (Sandbox Code Playgroud)
你可能会这么认为n / m * m == n.浮点世界再一次不同意:
>>> (1.0 / 103.0) * 103.0
0.99999999999999989
Run Code Online (Sandbox Code Playgroud)
或许也许奇怪的是,人们可能会认为这一切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
Run Code Online (Sandbox Code Playgroud)
请参阅每位计算机科学家应该了解的关于浮点数的内容,以便对问题进行精彩总结.
如果您需要精确的十进制表示,请查看十进制模块,这是自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')
Run Code Online (Sandbox Code Playgroud)
值得注意的是,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]
Run Code Online (Sandbox Code Playgroud)
从Python 3.1中的新功能文档:
Python现在使用David Gay的算法来查找不会改变其值的最短浮点表示.这应该有助于缓解围绕二进制浮点数的一些混淆.
使用像1.1这样的数字很容易看出它的重要性,它在二进制浮点数上没有精确的等价物.由于没有确切的等价,因此表达式会
float('1.1')计算为最接近的可表示值,该值可以是0x1.199999999999ap+0十六进制或1.100000000000000088817841970012523233890533447265625十进制.该最近的值仍然用于后续浮点计算.