[Tutor] Math: integers to a fractional power

Steven D'Aprano steve at pearwood.info
Tue Nov 16 00:10:32 CET 2010


Matthew Denaburg wrote:

>>>> -27**(1/3)
> -3.0
>>>> math.pow(-27, 1/3)
> Traceback (most recent call last):
>   File "<pyshell#23>", line 1, in <module>
>     math.pow(-27, 1/3)
> ValueError: math domain error
> 
> 	Is there something going on here that I am unaware of?

Yes, various things.

The precedence of the exponentiation operator ** is higher than that of 
the negation operator -, so -27**(1/3) is equivalent to:

- (27 ** (1/3))

and there is no attempt to raise a negative number to a float. Thus:

 >>> -9**0.5
-3.0

Secondly, there are always N Nth-roots of a number: the familiar real 
root (or roots), and complex roots. For example:

(-1)**2 = 1**2 = 1 so there are two square roots, +1 and -1.

The same holds for higher powers, only the roots can be imaginary or 
complex. (Note: you shouldn't take "real" and "imaginary" in their plain 
English meanings -- imaginary numbers are just as "real" as real 
numbers, it's just a little harder to point to examples.)

Python happens to return a complex root when using the ** operator:

 >>> (-27)**(1/3)
(1.5000000000000002+2.5980762113533156j)

Note the usual floating point issues: due to rounding, you don't always 
get the *exact* result:

 >>> ((-27)**(1/3))**3
(-26.999999999999993+1.0220990720455347e-14j)

On the other hand, the pow() function refuses to perform exponentiation 
of a negative integer. I don't know why they have different behaviour -- 
possibly an accident that different people wrote the code for each, or 
possibly there is some deliberate reason for it.

You might find the functions in the cmath (complex math) module useful 
for working with complex numbers.


-- 
Steven


More information about the Tutor mailing list