我的代码:
import math
import cmath
print "E^ln(-1)", cmath.exp(cmath.log(-1))
打印内容:
E^ln(-1) (-1+1.2246467991473532E-16j)
打印内容:
-1
(供参考,谷歌检查我的计算)
根据python.org上的文档,cmath.exp(x)
返回e^(x), cmath.log(x)
返回ln (x),所以除非我缺少分号或其他东西,这是一个非常简单的三行程序。
当我测试cmath.log(-1)
时,它返回π I (技术上是3.141592653589793j
)。这是对的。欧拉恒等式说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实际上都等于0,但它们似乎有最大的虚部,而4和5根本没有实部。
不好意思。非常沮丧。
正如您已经演示过的,cmath.log(-1)
并不完全返回 i*pi
。当然,完全返回pi
是不可能的,因为pi
是一个无理数…
现在你把e
提高到不完全是i*pi
的某个数的幂,你期望得到的正好是-1
。然而,如果cmath
返回,你会得到一个不正确的结果。(毕竟,exp(i*pi+epsilon)
不应该等于-1
——欧拉没有做出这样的声明!)。
无论如何,结果非常接近您所期望的——实数部分是-1
,虚数部分接近浮点精度。
似乎是一个四舍五入的问题。虽然-1+1.22460635382e-16j不是一个正确的值,但1.22460635382e-16j非常接近于零。我不知道如何解决这个问题,但一个快速而肮脏的方法是将数字四舍五入到点后的特定位数(可能是14 ?).
小于10^-15的值通常为零。计算机计算有一定的误差,通常在这个范围内。浮点表示是表示,而不是精确值。
这个问题是将有限空间中的无理数(如π)表示为浮点数所固有的。
你能做的最好的是过滤你的结果,如果它的值在给定的范围内,把它设置为零。
>>> 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)