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)
这种行为似乎不仅在理论上没有说明,而且在实践中也很奇怪!这解释了什么?
查看复数求幂的源代码表明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)
当a
和b
非常大时,这变为浮点无穷大减去浮点无穷大,即nan
.该nan
成果传播,经过几次操作,结果是(nan+nanj)
.Py_ADJUST_ERANGE2
只有errno
当它看到无穷大时才会设置,所以它会错过溢出并继续前进.
总之,Python只检查溢出的最终结果,而不是中间值,这会导致它错过中间的溢出,因为它总是nan
在最后.提升的表达式是这样OverflowError
做的,因为它们从不试图减去无穷大,因此最终会发现错误.它看起来不像是一个刻意的设计决定; 您可以通过更改溢出检查的工作方式来修复它.