首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在这个3.4.x版本的Python代码中,一些非常接近的浮点数会引起如此大的差异?

为什么在这个3.4.x版本的Python代码中,一些非常接近的浮点数会引起如此大的差异?
EN

Stack Overflow用户
提问于 2019-03-29 18:30:06
回答 2查看 120关注 0票数 1

当我执行这段代码时,它是生成算术散度的,或者不是用非常接近的浮点数,当数字达到2**n-p/q的形式时,它会产生一个可接受的结果,有时会产生非常快的散度。我读过一些关于浮点运算的文档,但我认为问题在其他地方,但在哪里?如果有人有主意我会很乐意理解这件事的..。

我尝试在Python3.4.5(32位)上执行代码,并在网上尝试使用repl.it和trinket在这里使用url[https://trinket.io/python3/d3f3655168],结果是相似的。

代码语言:javascript
复制
#this code illustrates arithmetical divergence with floating point numbers
# on Python 3.4 an 3.6.6

def ErrL(r):
    s=1
    L=[]
    for k in range(10):
        s=s*(r+1)-r
        L.append(s)
    return L

print(ErrL(2**11-2/3.0)) # this number generate a fast divergence in loop for
#[0.9999999999997726, 0.9999999995341113, 0.9999990457047261, 0.9980452851802966, -3.003907522359441, -8200.33724163292, -16799071.44994476, -34410100067.30351, -70483354973240.67, -1.4437340543685667e+17]

print(ErrL(2**12-1/3.0)) # this number generate a fast divergence in loop for
#[0.9999999999995453, 0.9999999981369001, 0.9999923674999991, 0.968732191662184, -127.09378815725313, -524756.5521508802, -2149756770.9781055, -8806836909202.637, -3.607867520470422e+16, -1.4780230608860496e+20]

print(ErrL(2**12-1/10.0)) # this number generate a fast divergence in loop for
#[0.9999999999995453, 0.9999999981369001, 0.9999923670652606, 0.9687286296662023, -127.11567712053602, -524876.117595124, -2150369062.0754633, -8809847014512.865, -3.609306223376185e+16, -1.478696666654989e+20]

print(ErrL(2**12-1/9.0)) # no problem here
#[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

print(ErrL(2**12-1/11.0)) # no problem here
#[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

我所期待的显然是一个十个1的向量!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-29 19:01:18

发散非常快的原因是数学。如果编写f(s) = (r+1) * s - r,很明显,导数是常数r+1。根据维基百科,IEE 754中的64位浮点数有53位的尾数。当r接近2**11时,最后一个位上的错误将需要小于5个步骤才能接近1,当数接近2**12时,它在第5次迭代时爆炸,这就是您得到的结果。

唉,40年前我学的数学还没坏……

票数 1
EN

Stack Overflow用户

发布于 2019-03-29 18:41:14

当使用Python2执行此代码时,整数之间的/表示整数除法(在Python3中现在称为// )。

因此,在本例中,2/31/3等都等于0,得到的是ErrL(2**11),.,它总是1。

对于Python3,2/3是一个浮点,而不是0,这解释了为什么得到不同的结果。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55423587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档