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: Bogus parsing of negative zeros in complex literals
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, mark.dickinson, pitrou, serhiy.storchaka
Priority: low Keywords:

Created on 2014-10-03 17:24 by pitrou, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (10)
msg228343 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-10-03 17:24
This may be a parser limitation...

>>> z = -0.-0.j
>>> z
(-0+0j)
>>> z.imag
0.0
>>> z = 0.-0.j
>>> z.imag
0.0
msg228345 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-03 17:28
This is not a bug, but a known and difficult-to-avoid issue with signed zeros and creating complex numbers from real and imaginary parts.  The safe way to do it is to use the `complex(real_part, imag_part)` construction.

In the first example, you're subtracting a complex number (0.j) from a float (-0.0).  The float gets promoted to a complex (by filling in an imaginary part of +0.0), and the imaginary literal is similarly treated as a complex number (by filling  in a 0.0 for the real part).  So the subtraction is doing:

  complex(-0.0, 0.0) - complex(0.0, -0.0)

which as expected gives a real part of -0.0, and an imaginary part of +0.0.
msg228346 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-03 17:29
Sorry; that should be:

  complex(-0.0, 0.0) - complex(0.0, 0.0)

The imaginary part is then worked out as (0.0 - 0.0), which (in all rounding modes but round-towards-negative) is 0.0.
msg228347 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-03 17:31
P.S.  The C standardisation folks tried to introduce the Imaginary type (optional for a conforming implementation) to get around exactly this type of problem, but it doesn't seem to have caught on in most mainstream compilers.
msg228351 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-10-03 17:38
FTR, a similar issue with regular floats:

>>> -0.0-0.0
-0.0
>>> (-0.0)-0.0
-0.0
>>> z = -0.0
>>> z - z
0.0
msg228352 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-03 17:45
Nope, no float issue here. :-)  Which part of the output do you think is wrong?

Your last (z - z) is doing ((-0.0) - (-0.0)), not (-0.0 - 0.0).  This is all following the IEEE 754 rules.
msg228353 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-10-03 17:46
Yes, the last part is ok. It's the preceding parts that are a bit surprising.
msg228354 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-10-03 17:47
Oops, I get it now. Sorry.
msg228356 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-03 17:50
> Oops, I get it now.

Okay. :-)

Just for the record, for anyone encountering this issue in the future, here's the relevant extract from section 6.3 of IEEE 754-2008:

"""
When the sum of two operands with opposite signs (or the difference of two operands with like signs) is exactly zero, the sign of that sum (or difference) shall be +0 in all rounding-direction attributes except roundTowardNegative; under that attribute, the sign of an exact zero sum (or difference) shall be −0. However, x + x = x − (−x) retains the same sign as x even when x is zero.
"""

It doesn't cover the "sum with like signs" or "difference with opposite signs" cases, I suppose because it should be obvious what happens in those cases.
msg228360 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2014-10-03 18:01
> It doesn't cover the "sum with like signs"

Ah, sorry, yes it does;  it's in the previous paragraph.

"""
[...] the sign of a sum, or of a difference x−y regarded as a sum x+(−y), differs from at most one of the addends’ signs
"""
History
Date User Action Args
2022-04-11 14:58:08adminsetgithub: 66738
2020-04-19 08:31:05serhiy.storchakasetpull_requests: - pull_request18927
2020-04-19 08:16:47serhiy.storchakasetnosy: + serhiy.storchaka

pull_requests: + pull_request18927
2014-10-03 18:01:45mark.dickinsonsetmessages: + msg228360
2014-10-03 17:50:31mark.dickinsonsetmessages: + msg228356
2014-10-03 17:47:03pitrousetmessages: + msg228354
2014-10-03 17:46:41pitrousetmessages: + msg228353
2014-10-03 17:45:47mark.dickinsonsetmessages: + msg228352
2014-10-03 17:38:39pitrousetmessages: + msg228351
2014-10-03 17:31:06mark.dickinsonsetmessages: + msg228347
2014-10-03 17:29:41mark.dickinsonsetmessages: + msg228346
2014-10-03 17:28:16mark.dickinsonsetstatus: open -> closed
resolution: not a bug
messages: + msg228345
2014-10-03 17:24:14pitroucreate