Search code examples
pythonpython-3.xcomplex-numbers

Why is Python creating a complex number here?


I'm getting a strange error in Python 3.8:

When I run this calculation, I get a complex number:

>>> (1.0 / (2.0 - 0.5222232592740141 * 92.16159106468214)) ** (1.0 / (10.0 + 1))
(0.6772850578932906+0.1988688362687656j) 

However, if I calculate this manually in Python I get a float answer:

>>> (1.0 / (2.0 - 0.5222232592740141 * 92.16159106468214))
-0.021678371395529073
>>> (1.0 / (10.0 + 1))
0.09090909090909091

>>> -0.021678371395529073 ** 0.09090909090909091
-0.7058780799007794

Why is this?


Solution

  • your not taking into account the negative at the start. what python will actually interpret

    -0.021678371395529073 ** 0.09090909090909091 as is really -(0.021678371395529073 ** 0.09090909090909091)

    So do the power with 2 positive numbers then apply the negative. However if you wrap the first number and negative together to python knows the negative applies to that first number not just the net result of the expression you get the complex number

    (-0.021678371395529073) ** 0.09090909090909091
    (0.6772850578932906+0.1988688362687656j)
    

    this is what happens in your real example as python knows the term is negative, not the result

    To explain why this is happening you have to look at the order of operations. In your expression you have two operations - and ** and you have two terms 0.021678371395529073, 0.09090909090909091

    below table lays out the order of operations, those that appear higher in the table are done first.

    Operator
    
    Description
    ()  Parentheses (grouping)
    f(args...)  Function call
    x[index:index]  Slicing
    x[index]    Subscription
    x.attribute Attribute reference
    **  Exponentiation
    ~x  Bitwise not
    +x, -x  Positive, negative
    *, /, % Multiplication, division, remainder
    +, -    Addition, subtraction
    <<, >>  Bitwise shifts
    &   Bitwise AND
    ^   Bitwise XOR
    |   Bitwise OR
    in, not in, is, is not, <, <=,  >,  >=,
    <>, !=, ==  Comparisons, membership, identity
    not x   Boolean NOT
    and Boolean AND
    or  Boolean OR
    lambda  Lambda expression
    

    from this table you can see that Exponentiation(**) has a higher precedent than Negation (-x). So that means python will first raise to the power of the two terms, then apply the negation to the result of that. So if you want the negation to be applied to the first number before raising to the power, then you need to wrap that in Parentheses.