首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在什么情况下,Python复合指数抛出一个OverflowError?

在什么情况下,Python复合指数抛出一个OverflowError?
EN

Stack Overflow用户
提问于 2013-08-14 22:18:24
回答 3查看 7.2K关注 0票数 4

我想找出这里的模式:

代码语言:javascript
复制
>>> 1e300 ** 2
OverflowError: (34, 'Result too large')
>>> 1e300j ** 2
OverflowError: complex exponentiation
>>> (1e300 + 1j) ** 2
OverflowError: complex exponentiation
>>> (1e300 + 1e300j) ** 2
(nan+nanj)

这种行为似乎不仅在理论上没有具体说明,而且在实践中也很奇怪!这是怎么解释的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-08-14 23:10:38

查看用于复杂指数的来源,就会发现Python只在计算结束时检查溢出。另外,对于小整数指数也有一个特例,它通过平方进行幂运算,这涉及到复数乘法。

代码语言:javascript
复制
r.real = a.real*b.real - a.imag*b.imag;
r.imag = a.real*b.imag + a.imag*b.real;

这是复乘法的公式。请注意以下事项:

代码语言:javascript
复制
a.real*b.real - a.imag*b.imag

ab非常大时,它变成浮点无穷大减去浮点无穷大,即nannan结果传播,经过几次操作后,结果是(nan+nanj)Py_ADJUST_ERANGE2只在看到无穷大时才设置errno,因此它错过了溢出并继续前进。

总之,Python只检查溢出的最终结果,而不是中间值,这会导致它错过中间的溢出,因为它在结束时是所有的nan。确实引起OverflowError的表达式是这样做的,因为它们从不试图减去无穷大,因此在结尾处会发现错误。它看起来不像是一个深思熟虑的设计决策;您可以通过改变溢出检查的工作方式来修复它。

票数 7
EN

Stack Overflow用户

发布于 2013-08-14 22:51:51

好吧,我很确定我已经搞清楚了。

首先,我注意到一件似乎有点可笑的事:

代码语言:javascript
复制
>>> (1e309j)**2
(nan+nanj)
>>> (1e308j)**2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: complex exponentiation

有意思的。也许这和复杂的指数根本没有关系。

代码语言:javascript
复制
>>> (1e309)**2
inf
>>> (1e308)**2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Result too large')

更有趣的是。让我们看看Python对1e3091e308的看法

代码语言:javascript
复制
>>> (1e308)
1e+308
>>> (1e309)
inf

最后,

代码语言:javascript
复制
>>> (1e309)**2
inf
>>> (1e309j)**2
(nan+nanj)

代码语言:javascript
复制
>>> (float('inf') + 1j) ** 2
(nan+nanj)

>>> (1e309j)
infj
>>> (1e309j)**2
(nan+nanj)

inf的任何操纵都给了我们inf。看起来复数(a + bi)的实现不太倾向于给出inf,而更倾向于给出(nan + nanj)。所以,通常返回inf的东西会返回(nan + nanj) --我不知道为什么会这样,也许对Python的infnan有更好理解的人可以跳进去。

简而言之,数字最终不再泛滥,并开始返回inf。用inf计算很容易,但是用接近它的数字进行计算就不容易了!这就是为什么1e309**2工作,而1e308 ** 2不工作。当与复数配对时,这(无论出于什么原因)给出了(nan + nanj)。我只是通过玩游戏机才发现这一点的--我很想看一个更彻底的解释!

编辑:@user2357112给出了一个更好的理由。计算复指数的方法可以包括inf - inf的计算,它返回nan。我将把这个留待显示模式,但他的回答给出了理由。

顺便说一句,我觉得这很有趣:

代码语言:javascript
复制
>>> (float('inf') + 1j) ** 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: complex exponentiation
>>> (float('inf') + 1j) 
(inf+1j)
票数 3
EN

Stack Overflow用户

发布于 2013-08-14 22:42:36

Python整数值可以自动提升到长时间的任意精度:

代码语言:javascript
复制
>>> (10**300)**2
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

由于IEEE浮点的限制,浮点数溢出

代码语言:javascript
复制
>>> float(10**300)**2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Result too large')

Python复杂的组件是一个浮点类,但也会发生相同的溢出:

代码语言:javascript
复制
>>> isinstance(complex(1).real,float)
True
>>> isinstance(complex(1).imag,float)
True

取通常的最大双精度值:

代码语言:javascript
复制
>>> max_double=1.7976931348623157e+308

在浮点范围内执行大多数增加该值的步骤,然后得到inf

代码语言:javascript
复制
>>> max_double*10
inf
>>> max_double*max_double
inf
>>> max_double*max_double*max_double*max_double
inf
>>> max_double++10**(308-15)
inf

如果在FP窗口外,mantisa和指数不变:

代码语言:javascript
复制
>>> md+10**(308-17)
1.7976931348623157e+308
>>> max_double**1.0000000000000001
1.7976931348623157e+308

可以看到溢出:

代码语言:javascript
复制
>>> max_double**1.000000000000001
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Result too large')

但作为在文件中说明,它的应用并不一致:

由于C语言中浮点异常处理缺乏标准化,大多数浮点操作也没有被检查。

在这里可以看到:

代码语言:javascript
复制
>>> (1e300+1e300j)*(1e300+1e300j)
(nan+infj)
>>> (1e300+1e300j)**2
(nan+nanj)
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18243270

复制
相关文章

相似问题

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