在Haskell中,我试图找到负整数的立方根,例如-1,但没有成功。
我使用过(-1)**(1/3),但这会返回一个NaN。我认为这可能与(1/3)分数的类型有关,但使用(1/3 :: Double)也没有成功。
结果,我的问题是如何使用Haskell找到-1的立方根,以便它不返回NaN?
答案 0 :(得分: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。
如果只需要一个可以处理负数的立方根,那么给出的其他答案应该可以正常工作,但@ Istvan的答案应该使用signum
代替{ {1}},像这样:
sign
如果你想要一个更通用的整数根函数用于实数,请注意,即使cbrt x = signum x * abs x ** (1/3)
,也没有正数的负数的第n个根,所以这是你可以做的最好的:< / p>
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
答案 1 :(得分:1)
我不了解Haskell,但你可以这样做: sign(x)* abs(x)**(1/3)
答案 2 :(得分:1)
关于ghci,我已经做了一些似乎可以解决问题的事情:
let cbrt x = if x < 0 then -((-x) ** (1/3)) else x ** (1/3)
简单的Cuberoot功能。
由于我还在学习,我不知道这是否是一个正确的解决方案,所以如果有什么遗漏或错误,请告诉我;)