Python thinks Euler has identity issues (cmath returning funky results)
Question: My code:

    
    
    import math
    import cmath
    print "E^ln(-1)", cmath.exp(cmath.log(-1))
    

What it prints:

    
    
    E^ln(-1) (-1+1.2246467991473532E-16j)
    

What it should print:

    
    
    -1
    

(For Reference, [Google checking my
calculation](https://www.google.com/search?q=ln+-1&oq=ln+-1&aqs=chrome.0.57j0j62l3.1058j0&sourceid=chrome&ie=UTF-8#sclient=psy-
ab&q=e%5E%28ln+-1%29&oq=e%5E%28ln+-1%29&gs_l=serp.3...1276195.1278527.0.1278866.4.4.0.0.0.2.492.1669.2-1j0j3.4.0...0.0.0..1c.1.17.psy-
ab.Qu5LLcMf-
RM&pbx=1&bav=on.2,or.r_cp.r_qf.&bvm=bv.47810305,d.cGE&fp=9cc36caf4d2cdbc4&biw=1600&bih=813))

According to [the documentation at
python.org](http://docs.python.org/2/library/cmath.html) `cmath.exp(x)`
returns e^(x), and `cmath.log(x)` returns ln (x), so unless I'm missing a
semicolon or something , this is a pretty straightforward three line program.

When I test `cmath.log(-1)` it returns π _i_ (technically
`3.141592653589793j`). Which is right. [Euler's
identity](http://en.wikipedia.org/wiki/Euler%27s_identity) says e^(π _i_) =
-1, yet Python says when I raise e^(π _i_), I get some kind of crazy talk
(specifically `-1+1.2246467991473532E-16j`).

Why does Python hate me, and how do I appease it?

Is there a library to include to make it do math right, or a sacrifice I have
to offer to van Rossum? Is this some kind of floating point precision issue
perhaps?

The big problem I'm having is that the precision is off enough to have other
values appear closer to 0 than actual zero in the final function (not shown),
so boolean tests are worthless (i.e. `if(x==0)`) and so are local minimums,
etc...

For example, in an iteration below:

    
    
    X = 2 Y= (-2-1.4708141202500006E-15j)
    X = 3 Y= -2.449293598294706E-15j
    X = 4 Y= -2.204364238465236E-15j
    X = 5 Y= -2.204364238465236E-15j
    X = 6 Y= (-2-6.123233995736765E-16j)
    X = 7 Y= -2.449293598294706E-15j
    

3 & 7 are both actually equal to zero, yet they appear to have the largest
imaginary parts of the bunch, and 4 and 5 don't have their real parts at all.

Sorry for the tone. Very frustrated.


Answer: As you've already demonstrated, `cmath.log(-1)` doesn't return **exactly**
`i*pi`. Of course, returning `pi` exactly is impossible as `pi` is an
irrational number...

Now you raise `e` to the power of something that isn't exactly `i*pi` and you
expect to get exactly `-1`. However, if `cmath` returned that, you would be
getting an incorrect result. (After all, `exp(i*pi+epsilon)` shouldn't equal
`-1` \-- Euler doesn't make that claim!).

For what it's worth, the result is very close to what you expect -- the real
part is `-1` with an imaginary part close to floating point precision.

