Here is the scenario:
In [5]: (2.0 - 5.0**(0.5)) ** (1.0/3.0)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-5-d064023f1ac5> in <module>()
----> 1 (2.0 - 5.0**(0.5)) ** (1.0/3.0)
ValueError: negative number cannot be raised to a fractional power
In [7]: -1.0 ** (1.0/3.0)
Out[7]: -1.0
The above operation is being done on a python interpreter. For the first expression, it is giving value error and says that negative number can't have fractional power
!! So, firstly, why is this error as obviously, -ve numbers can have cube root or fifth root etc. Also, if that is the case, it should be consistent while in second case, it gives no error when -1 is raised to fractional power (1/3).
Can someone explain why is this the case?
The **
operator has specific binding behaviour; from the power operator documentation:
The power operator binds more tightly than unary operators on its left; it binds less tightly than unary operators on its right.
[...]
Thus, in an unparenthesized sequence of power and unary operators, the operators are evaluated from right to left (this does not constrain the evaluation order for the operands):
-1**2
results in-1
.
So your second example is executed as:
-(1.0 ** (1.0/3.0))
That is to say, the -
unary operator applies to the result of **
as that operator binds more tightly. As a result you have positive number is raised to the power 1/3rd, and only then made negative.
In your first example, the expression is parsed as
(2.0 - (5.0**(0.5))) ** (1.0/3.0)
There is no unary operator here, but the **
power operator does have a higher precedence than the binary -
subtraction operator.
This then resolves as
(2.0 - 2.23606797749979) ** (1.0/3.0)
which is
(-0.2360679774997898) ** (1.0/3.0)
so is trying to raise a negative number to a fraction.
Python 2 **
(and the pow()
function) don't support producing a complex number support when the inputs are at most float
objects. Convert your negative float value to a complex()
number first:
>>> (-1.0) ** 0.5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: negative number cannot be raised to a fractional power
>>> (-1+0j) ** 0.5
(6.123233995736766e-17+1j)
>>> (2+0j - 5.0**(0.5)) ** (1.0/3.0)
(0.30901699437494756+0.535233134659635j)
This changed in Python 3, where a complex result is returned for a negative number raised to a fractional power.