如何找到负整数的立方根,使其不返回NaN?

时间:2017-09-17 14:04:00

标签: haskell

在Haskell中,我试图找到负整数的立方根,例如-1,但没有成功。

我使用过(-1)**(1/3),但这会返回一个NaN。我认为这可能与(1/3)分数的类型有关,但使用(1/3 :: Double)也没有成功。

结果,我的问题是如何使用Haskell找到-1的立方根,以便它不返回NaN?

3 个答案:

答案 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功能。

由于我还在学习,我不知道这是否是一个正确的解决方案,所以如果有什么遗漏或错误,请告诉我;)