Python认为Euler有身份问题(cmath返回时髦的结果)

时间:2013-06-12 17:55:41

标签: python floating-point cmath

我的代码:

import math
import cmath
print "E^ln(-1)", cmath.exp(cmath.log(-1))

它打印的内容:

E^ln(-1) (-1+1.2246467991473532E-16j)

应该打印什么:

-1

(供参考,Google checking my calculation

根据the documentation at python.org cmath.exp(x)返回e ^(x),cmath.log(x)返回ln(x),所以除非我缺少分号或其他内容,否则这是非常简单的三线计划。

当我测试cmath.log(-1)时,它返回π i (技术上3.141592653589793j)。哪个是对的。 Euler's identity说e ^(π i )= -1,但Python说当我举起e ^(π i )时,我会得到某种疯狂的谈话(具体是-1+1.2246467991473532E-16j)。

为什么Python讨厌我,我该如何安抚它?

是否有一个图书馆可以让它做正确的数学运算,还是我必须为van Rossum提供的牺牲?这可能是某种浮点精度问题吗?

我遇到的一个大问题是,精度足以使其他值在最终函数(未显示)中看起来比实际零更接近0,因此布尔测试毫无价值(即if(x==0))当地的最低限度等......

例如,在下面的迭代中:

X = 2 Y= (-2-1.4708141202500006E-15j)
X = 3 Y= -2.449293598294706E-15j
X = 4 Y= -2.204364238465236E-15j
X = 5 Y= -2.204364238465236E-15j
X = 6 Y= (-2-6.123233995736765E-16j)
X = 7 Y= -2.449293598294706E-15j

3& 7实际上都等于零,但它们似乎具有最大的虚部,而4和5根本没有它们的真实部分。

对不起。非常沮丧。

3 个答案:

答案 0 :(得分:3)

正如您已经证明的那样,cmath.log(-1)不会返回完全 i*pi。当然,完全归还pi是不可能的,因为pi是一个无理数......

现在,您将e提升到不完全i*pi的强大功能,并且您希望得到-1。但是,如果cmath返回该值,则会得到错误的结果。 (毕竟,exp(i*pi+epsilon)不应该等于-1 - 欧拉没有提出这种说法!)。

对于它的价值,结果非常接近你所期望的 - 真实部分是-1,虚部接近浮点精度。

答案 1 :(得分:1)

这似乎是一个四舍五入的问题。虽然-1 + 1.22460635382e-16j不是正确的值,但1.22460635382e-16j非常接近于零。我不知道你怎么能解决这个问题,但一个快速而肮脏的方法可能是在点之后将数字四舍五入到一定数量的数字(14可能?)。

小于10 ^ -15的任何东西通常为零。计算机计算有一定的误差,通常在该范围内。浮点表示是表示,而不是精确值。

答案 2 :(得分:0)

问题是将有限空间中的无理数(如π)表示为浮点所固有的。

您可以做的最好的事情是过滤您的结果,如果其值在给定范围内,则将其设置为零。

>>> tolerance = 1e-15
>>> def clean_complex(c):
...   real,imag = c.real, c.imag
...   if -tolerance < real < tolerance:
...     real = 0
...   if -tolerance < imag < tolerance:
...     imag = 0
...   return complex(real,imag)
... 
>>> clean_complex( cmath.exp(cmath.log(-1)) )
(-1+0j)