This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Type: Complex number representation round-trip doesn't work with signed zero values behavior Python 3.3
process
Status: Resolution: closed not a bug Eric Wieser, eric.smith, ezio.melotti, mark.dickinson, mjacob, skrah normal

Created on 2013-03-02 11:28 by mjacob, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (6)
msg183313 - (view) Author: Manuel Jacob (mjacob) * Date: 2013-03-02 11:28
```When evaluating, signed zero complex numbers aren't recovered correctly.
>>> -0j
(-0-0j)
>>> (-0-0j)
0j
>>> 0j
0j

According to http://docs.python.org/dev/reference/datamodel.html#object.__repr__ the representation can be used to recreate an object with the same value. Shouldn't this also be possible with complex numbers?

When using complex('...'), round-trip works correctly. While this can be used to recover the exact number, i find it confusing that complex('...') isn't the same as eval('...').
>>> complex('-0j')
-0j
>>> complex('(-0-0j)')
(-0-0j)
>>> complex('0j')
0j```
msg183342 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2013-03-02 19:17
```This is not easy to avoid, I'm afraid, and it's a consequence of Python's usual rules for mixed-type arithmetic:  (-0-0j) is interpreted as 0 - (0.0 + 0.0j) --- that is, the 0j is promoted to a complex instance (by giving it zero real part) before the subtraction is performed.  Then the real part of the result is computed as 0.0 - 0.0, which is 0.0.  Note that the first 0.0 comes from converting the *integer* 0 to a complex number.  If you do -0.0-0.0j you'll see a different result:

>>> -0.0-0.0j
(-0+0j)```
msg183343 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2013-03-02 19:18
`An aside:  C99 gets around this problem by allowing an (optional) Imaginary type, separate from Complex.  Very few compilers support it, though.`
msg374872 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2020-08-05 11:12
```The issue of changing the complex repr came up again in #41485, which has been closed as a duplicate of this issue.

> BTW I don't want repr() of a complex number to use the complex(..., ...)
notation -- it's too verbose.

FWIW, I'd be +1 on changing the complex repr, but given Guido's opposition we're probably looking at a PEP to make that happen, and I don't have the bandwidth or the energy to push such a PEP through.```
msg374873 - (view) Author: Mark Dickinson (mark.dickinson) * Date: 2020-08-05 11:13
`Also related: #40269`
msg374878 - (view) Author: Eric Wieser (Eric Wieser) Date: 2020-08-05 12:03
```> BTW I don't want repr() of a complex number to use the complex(..., ...)

A compromise would be to only use this notation if signed zeros are involved.

---

Another option would be to use slightly unusual reprs for these complex numbers, which at least round-trip:

def check(s, v):
c = eval(s)
# use string equality, because it's the easiest way to compare signed zeros
cs = f"complex({c.real}, {c.imag})"
vs = f"complex({v.real}, {v.imag})"
assert vs == cs, f' expected {vs} got {cs}'

check("-(0+0j)", complex(-0.0, -0.0))
check("(-0.0-0j)", complex(-0.0, 0.0))  # non-intuitive
check("-(-0.0-0j)", complex(0.0, -0.0))  # non-intuitive

Which I suppose would extend to complex numbers containing just one signed zero

check("(-0.0-1j)", complex(-0.0, -1))
check("-(0.0-1j)", complex(-0.0, 1))
check("-(1+0j)", complex(-1, -0.0))
check("-(-1+0j)", complex(1, -0.0))

Only two of these reprs are misleading for users who don't understand what's going on, the rest will just strike users as odd.```
History
Date User Action Args