2017-09-17 59 views
4

在Haskell,我試圖找到一個負整數的立方根,例如,-1,但沒有成功。如何查找負整數的立方體根,使其不返回NaN?

我已經使用(-1)**(1/3),但這一返回一個爲NaN。我認爲這可能與(1/3)分數類型有關,但使用(1/3 :: Double)也沒有成功。

其結果是,我的問題是如何找到使用哈斯克爾,使其不返回的NaN -1的立方根?

+2

見https://wiki.haskell.org/Power_function – chepner

+0

兩個Haskell和Python的返回'第一根複雜-1'(〜0.5-0.866i) - 我想最編程語言也可以這樣做,只要使用合適的複雜類型即可。當使用雙打時,NaN會出現,因爲結果不是真實的。 – chi

回答

1

我不知道哈斯克爾,但你可以做這樣的事情: 號(X)* ABS(X)**(1/3)

1

在ghci中我已經做了一些,似乎解決你的問題:

let cbrt x = if x < 0 then -((-x) ** (1/3)) else x ** (1/3) 

一個簡單的cuberoot函數。

由於我還在學習,我不知道這是一個妥善的解決辦法,所以請讓我知道如果有什麼東西丟失或錯誤;)

5

對於實數,Haskell的操作(**)只被定義對於指數(右側)爲整數值時的負基(左側)值。如果打你的怪,注意,C函數pow的工作方式:

printf("%f\n", pow(-1.0, 1.0/3.0)); // prints "-nan", for me 

也是如此Python的**操作:

print((-1.0)**(1.0/3.0)) 
# gives: ValueError: negative number cannot be raised to fractional power 

的問題是局部的數學之一。將負面基礎提升爲非整體力量的「正確答案」並不明顯。例如,參見question on the Mathematics SO

如果需要立方根,可以處理負數,給出其他答案應該工作正常,但@伊什特萬的答案應該使用signum代替sign,像這樣:

cbrt x = signum x * abs x ** (1/3) 

如果你需要一個更一般的積分根函數的實數,被警告即使是n,也沒有負數的真正的第n根,所以這是你可以做的最好的:

-- | Calculate nth root of b 
root :: (Integral n, RealFloat b) => n -> b -> b 
root n b | odd n && b < 0 = - abs b ** overn 
     | otherwise  = b ** overn 
    where overn = 1/fromIntegral n 

這給:

> root 3 (-8) 
-2.0 
> root 4 (-8) 
NaN  -- correct, as no real root exists 
>