在Haskell,我試圖找到一個負整數的立方根,例如,-1,但沒有成功。如何查找負整數的立方體根,使其不返回NaN?
我已經使用(-1)**(1/3),但這一返回一個爲NaN。我認爲這可能與(1/3)分數類型有關,但使用(1/3 :: Double)也沒有成功。
其結果是,我的問題是如何找到使用哈斯克爾,使其不返回的NaN -1的立方根?
在Haskell,我試圖找到一個負整數的立方根,例如,-1,但沒有成功。如何查找負整數的立方體根,使其不返回NaN?
我已經使用(-1)**(1/3),但這一返回一個爲NaN。我認爲這可能與(1/3)分數類型有關,但使用(1/3 :: Double)也沒有成功。
其結果是,我的問題是如何找到使用哈斯克爾,使其不返回的NaN -1的立方根?
我不知道哈斯克爾,但你可以做這樣的事情: 號(X)* ABS(X)**(1/3)
在ghci中我已經做了一些,似乎解決你的問題:
let cbrt x = if x < 0 then -((-x) ** (1/3)) else x ** (1/3)
一個簡單的cuberoot函數。
由於我還在學習,我不知道這是一個妥善的解決辦法,所以請讓我知道如果有什麼東西丟失或錯誤;)
對於實數,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
>
見https://wiki.haskell.org/Power_function – chepner
兩個Haskell和Python的返回'第一根複雜-1'(〜0.5-0.866i) - 我想最編程語言也可以這樣做,只要使用合適的複雜類型即可。當使用雙打時,NaN會出現,因爲結果不是真實的。 – chi