2017-02-12 34 views
3

repl.it和Windows中的控制檯上使用Python 3.5時,我得到了錯誤的立方體根的答案。Python中的立方根錯誤值

當輸入是(-1)**(1/3), 我得到複數(0.5000000000000001 + 0.8660254037844386j)作爲答案,它應該簡單地爲-1。根源下的任何負值似乎都會給出一個複雜的結果。

我做錯了什麼?

+1

爲什麼它應該是-1? –

+5

[你正在得到正確的答案](http://math.stackexchange.com/questions/8760/what-are-the-three-cube-roots-of-1),但它只是3個可能的答案之一。 – roganjosh

+0

@omri_saadon爲什麼它不應該? – Copperfield

回答

1

帶負數的冪求冪通常涉及複數,所以當Python看到負數時會切換到複數。這種取冪通常是多變的,Python並不總是返回你可能期望的值。

對於1/3電力與現實依據的特殊情況下,你可以寫這樣的功能:

def cubeRoot(x): 
    if x >= 0: 
     return x**(1/3) 
    else: 
     return -(-x)**(1/3) 

這將給預期實際立方根。

+1

在仔細研究這個之後,我似乎無法找到一種方法,在這種情況下,所有3都可以返回,就像在這個答案中強制實際的數字一樣。你知道這種方法是否存在? – roganjosh

+0

例如,我嘗試了[這裏]的兩個方法(http://stackoverflow.com/questions/1361740/cubic-root-of-the-negative-number-on-python/1362288),並且正在報告真實根目錄作爲'-1 + 1.2246467991473532e-16j'。這僅僅是爲了我自己的好奇心,OP沒有要求。 – roganjosh

+1

1/3不能表示爲浮點數,所以有多於3個值(-1)** x,其中x是最接近浮點數的1/3。 –

0

你得到的正是這種答案,因爲電源運算符計算

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不完全是相同名稱的數學常數,並且三角函數也是精確數學函數的近似值,所以出現浮點錯誤。

1

其實,Python並不知道你正在使用一個立方體根!

它所看到的只是一個浮點參數,其值接近0.3333333333 ...,但由於表示的有限性,不可能猜測您的意思恰好是1/3。

因此,所有了Python可以做的是求助於的負鹼基到真實電源(主分支)的冪的通常的定義,通過式

(-x)^y = exp(y(ln(x) + iπ) = exp(y ln(x)) (cos(yπ) + i sin(yπ)) 

其產生的複數值。