在repl.it和Windows中的控制檯上使用Python 3.5時,我得到了錯誤的立方體根的答案。Python中的立方根錯誤值
當輸入是(-1)**(1/3)
, 我得到複數(0.5000000000000001 + 0.8660254037844386j)作爲答案,它應該簡單地爲-1。根源下的任何負值似乎都會給出一個複雜的結果。
我做錯了什麼?
在repl.it和Windows中的控制檯上使用Python 3.5時,我得到了錯誤的立方體根的答案。Python中的立方根錯誤值
當輸入是(-1)**(1/3)
, 我得到複數(0.5000000000000001 + 0.8660254037844386j)作爲答案,它應該簡單地爲-1。根源下的任何負值似乎都會給出一個複雜的結果。
我做錯了什麼?
帶負數的冪求冪通常涉及複數,所以當Python看到負數時會切換到複數。這種取冪通常是多變的,Python並不總是返回你可能期望的值。
對於1/3電力與現實依據的特殊情況下,你可以寫這樣的功能:
def cubeRoot(x):
if x >= 0:
return x**(1/3)
else:
return -(-x)**(1/3)
這將給預期實際立方根。
在仔細研究這個之後,我似乎無法找到一種方法,在這種情況下,所有3都可以返回,就像在這個答案中強制實際的數字一樣。你知道這種方法是否存在? – roganjosh
例如,我嘗試了[這裏]的兩個方法(http://stackoverflow.com/questions/1361740/cubic-root-of-the-negative-number-on-python/1362288),並且正在報告真實根目錄作爲'-1 + 1.2246467991473532e-16j'。這僅僅是爲了我自己的好奇心,OP沒有要求。 – roganjosh
1/3不能表示爲浮點數,所以有多於3個值(-1)** x,其中x是最接近浮點數的1/3。 –
你得到的正是這種答案,因爲電源運算符計算
x**y = exp(y*ln(x))
,如果x
不是正實則其對數從複對數的主枝計算
ln(u+i*v)=0.5*ln(u²+v²) + i*arg(u+i*v)
哪裏在數學圖書館術語arg(u+i*v)=atan2(v,u)
。
因此ln(-1)=i*pi
和
(-1)**(1.0/3)=exp(i*pi/3)=cos(pi/3)+i*sin(pi/3)
其中有你得到了價值。因爲y=1.0/3
不是完全1/3
,pi
不完全是相同名稱的數學常數,並且三角函數也是精確數學函數的近似值,所以出現浮點錯誤。
其實,Python並不知道你正在使用一個立方體根!
它所看到的只是一個浮點參數,其值接近0.3333333333 ...,但由於表示的有限性,不可能猜測您的意思恰好是1/3。
因此,所有了Python可以做的是求助於的負鹼基到真實電源(主分支)的冪的通常的定義,通過式
(-x)^y = exp(y(ln(x) + iπ) = exp(y ln(x)) (cos(yπ) + i sin(yπ))
其產生的複數值。
爲什麼它應該是-1? –
[你正在得到正確的答案](http://math.stackexchange.com/questions/8760/what-are-the-three-cube-roots-of-1),但它只是3個可能的答案之一。 – roganjosh
@omri_saadon爲什麼它不應該? – Copperfield