Strange things happen when i try to find the cube root of a number.
The following code returns me undefined. In cmd : -1.#IND
cout<<pow(( double )(20.0*(-3.2) + 30.0),( double )1/3)
While this one works perfectly fine. In cmd : 4.93242414866094
cout<<pow(( double )(20.0*4.5 + 30.0),( double )1/3)
From mathematical way it must work since we can have the cube root from a negative number. Pow is from Visual C++ 2010 math.h library. Any ideas?
I think you should not confuse exponentiation with the nth-root of a number. See the good old Wikipedia
The power
1/3
is a special case. In general, non-integral powers of negative numbers are complex. It wouldn't be practical for pow to check for special cases like integer roots, and besides,1/3
as a double is not exactly 1/3!I don't know about the visual C++ pow, but my man page says under errors:
You'll have to use a more specialized cube root function if you want cube roots of negative numbers - or cut corners and take absolute value, then take cube root, then multiply the sign back on.
Note that depending on context, a negative number
x
to the1/3
power is not necessarily the negative cube root you're expecting. It could just as easily be the first complex root,x^(1/3) * e^(pi*i/3)
. This is the convention mathematica uses; it's also reasonable to just say it's undefined.pow( x, y )
is the same as (i.e. equivalent to)exp( y * log( x ) )
if log(x) is invalid then pow(x,y) is also.
Similarly you cannot perform 0 to the power of anything, although mathematically it should be 0.
Here's a little function I knocked up.
It uses Newton-Raphson to find a cube root.
Sometime Newton -Raphson gets stuck, if the root is very close to 0 then the derivative can get large and it can oscillate. So I've clamped and forced it to restart if that happens. If you need more accuracy you can change the FLT_EPSILONs.
pow(x, y)
from<cmath>
does NOT work if x is negative and y is non-integral.This is a limitation of
std::pow
, as documented in the C standard and on cppreference:There are a couple ways around this limitation:
Cube-rooting is the same as taking something to the 1/3 power, so you could do
std::pow(x, 1/3.)
.In C++11, you can use
std::cbrt
. C++11 introduced both square-root and cube-root functions, but no generic n-th root function that overcomes the limitations ofstd::pow
.While (-1)^3 = -1, you can't simply take a rational power of a negative number and expect a real response. This is because there are other solutions to this rational exponent that are imaginary in nature.
http://www.wolframalpha.com/input/?i=x^(1/3),+x+from+-5+to+0
Similarily, plot x^x. For x = -1/3, this should have a solution. However, this function is deemed undefined in R for x < 0.
Therefore, don't expect math.h to do magic that would make it inefficient, just change the signs yourself.