Cubic root of the negative number on python

Can someone help me to find a solution on how to calculate a cubic root of the negative number using python?

>>> math.pow(-3, float(1)/3)
nan

it does not work. Cubic root of the negative number is negative number. Any solutions?


A simple use of De Moivre's formula, is sufficient to show that the cube root of a value, regardless of sign, is a multi-valued function. That means, for any input value, there will be three solutions. Most of the solutions presented to far only return the principle root. A solution that returns all valid roots, and explicitly tests for non-complex special cases, is shown below.

import numpy
import math
def cuberoot( z ):
    z = complex(z)
    x = z.real
    y = z.imag
    mag = abs(z)
    arg = math.atan2(y,x)
    return [ mag**(1./3) * numpy.exp( 1j*(arg+2*n*math.pi)/3 ) for n in range(1,4) ]

Edit: As requested, in cases where it is inappropriate to have dependency on numpy, the following code does the same thing.

def cuberoot( z ):
    z = complex(z) 
    x = z.real
    y = z.imag
    mag = abs(z)
    arg = math.atan2(y,x)
    resMag = mag**(1./3)
    resArg = [ (arg+2*math.pi*n)/3. for n in range(1,4) ]
    return [  resMag*(math.cos(a) + math.sin(a)*1j) for a in resArg ]

math.pow(abs(x),float(1)/3) * (1,-1)[x<0]

You could use:

-math.pow(3, float(1)/3)

Or more generally:

if x > 0:
    return math.pow(x, float(1)/3)
elif x < 0:
    return -math.pow(abs(x), float(1)/3)
else:
    return 0

You can get the complete (all n roots) and more general (any sign, any power) solution using:

import cmath

x, t = -3., 3  # x**(1/t)

a = cmath.exp((1./t)*cmath.log(x))
p = cmath.exp(1j*2*cmath.pi*(1./t))

r = [a*(p**i) for i in range(t)]

Explanation: a is using the equation xu = exp(u*log(x)). This solution will then be one of the roots, and to get the others, rotate it in the complex plane by a (full rotation)/t.


Taking the earlier answers and making it into a one-liner:

import math
def cubic_root(x):
    return math.copysign(math.pow(abs(x), 1.0/3.0), x)