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

Jas*_*rff 4 python floating-point complex-numbers

我试图找出这里的模式:

>>> 1e300 ** 2
OverflowError: (34, 'Result too large')
>>> 1e300j ** 2
OverflowError: complex exponentiation
>>> (1e300 + 1j) ** 2
OverflowError: complex exponentiation
>>> (1e300 + 1e300j) ** 2
(nan+nanj)
Run Code Online (Sandbox Code Playgroud)

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

use*_*ica 7

查看复数求幂的源代码表明Python仅在计算结束时检查溢出.此外,还有一个小整数指数的特殊情况,它通过平方使用取幂,这涉及复数乘法.

r.real = a.real*b.real - a.imag*b.imag;
r.imag = a.real*b.imag + a.imag*b.real;
Run Code Online (Sandbox Code Playgroud)

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

a.real*b.real - a.imag*b.imag
Run Code Online (Sandbox Code Playgroud)

ab非常大时,这变为浮点无穷大减去浮点无穷大,即nan.该nan成果传播,经过几次操作,结果是(nan+nanj).Py_ADJUST_ERANGE2只有errno当它看到无穷大时才会设置,所以它会错过溢出并继续前进.

总之,Python只检查溢出的最终结果,而不是中间值,这会导致它错过中间的溢出,因为它总是nan在最后.提升的表达式是这样OverflowError做的,因为它们从不试图减去无穷大,因此最终会发现错误.它看起来不像是一个刻意的设计决定; 您可以通过更改溢出检查的工作方式来修复它.

  • -1:这是一个非常好的答案,但语句`提升OverflowError的表达式是这样做的,因为它们从不试图减去无穷大,所以错误被结束发现.完全是错误的. (2认同)