In Haskell, I have tried to find the cube root of a negative integer, for example, -1, without success.
I have used (-1) ** (1/3), but this returns a NaN. I thought that this might have something to do with type of the (1/3) fraction, but using (1/3 :: Double) yielded no success either.
As a result, my question is how can one find the cube root of -1 using Haskell so that it doesn't return NaN?
For real numbers, the Haskell operator (**)
is only defined for negative base (left-hand side) values when the exponent (right-hand side) is integer-valued. If this strikes you as strange, note that the C function pow
behaves the same way:
printf("%f\n", pow(-1.0, 1.0/3.0)); // prints "-nan", for me
and so does Python's **
operator:
print((-1.0)**(1.0/3.0))
# gives: ValueError: negative number cannot be raised to fractional power
The problem is partially a mathematical one. The "correct answer" for raising a negative base to a non-integral power is far from obvious. See, for example, this question on the Mathematics SO.
If you only need a cube root that can handle negative numbers, the other answers given should work fine, except that @Istvan's answer should use signum
instead of sign
, like this:
cbrt x = signum x * abs x ** (1/3)
If you want a more general integral root function for real numbers, be warned that for even n
, there are no nth roots of negative numbers that are real, so this is about the best you can do:
-- | 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
This gives:
> root 3 (-8)
-2.0
> root 4 (-8)
NaN -- correct, as no real root exists
>
I don't know Haskell, but you can do something like this: sign(x) * abs(x) ** (1/3)
On ghci I've done something that seems to solve your problem:
let cbrt x = if x < 0 then -((-x) ** (1/3)) else x ** (1/3)
A simple cuberoot function.
As I'm still learning I don't know if this is a proper solution, so please let me know if there's something missing or wrong ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With