Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

edge case when parsing complex numbers #105027

Closed
mattip opened this issue May 27, 2023 · 4 comments
Closed

edge case when parsing complex numbers #105027

mattip opened this issue May 27, 2023 · 4 comments
Labels
stdlib Python modules in the Lib dir

Comments

@mattip
Copy link
Contributor

mattip commented May 27, 2023

Bug report

A clear and concise description of what the bug is.
Include a minimal, reproducible example (https://stackoverflow.com/help/minimal-reproducible-example), if possible.

Parsing -1.0j with no real part will assume the real part is -0, not +0. This is a change from Python2. Is it intentional? PyPy3 will assume +0. This is the root cause of this PyPy issue

$ python3.11
Python 3.11.3 (main, Apr  5 2023, 14:14:37) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> -1.0j
(-0-1j)
>>> 0-1.0j
-1j
>>> 

Your environment

Debian-provided python3 all do this (python3.9, python3.10, python3.11).

  • CPython versions tested on:
  • Operating system and architecture:
    Debian, CPython 3.9, 3.10, 3.11
@mattip mattip added the type-bug An unexpected behavior, bug, or error label May 27, 2023
@arhadthedev arhadthedev added the stdlib Python modules in the Lib dir label May 27, 2023
@arigo
Copy link
Contributor

arigo commented May 27, 2023

Note that the CPython3 behavior almost makes sense: the expression -1j really means -(1j), and if you do a=1j; -a then you get -0-1j. This is different from doing the subtraction 0-1j, which gives a result with a positive-zero real part. It's the same difference that also occurs without complex number, between -0.0 and 0-0.0.

It only "almost" makes sense, because the detail that confuses matter is that the result of the expression 0-1j is printed as -1j; but the result of the expression -1j is printed as (-0-1j)... (also, the result of the expression (-0-1j) is printed as -1j, because need the expression (-0.0-1j) to print (-0-1j)).

@mdickinson
Copy link
Member

Yes, the Python 3 behaviour, and the change w.r.t. Python 2, is intentional.

1j is a complex number with real part +0.0 and imaginary part 1.0. The unary - negates both the real and imaginary part. In Python 2, there was a peculiar AST "optimization" that effectively absorbed the - into the literal.

@arigo: In 0 - 1j we're subtracting the complex number (0.0, 1.0) from the complex number (after coercing the int) (0.0, 0.0). The real part is therefore 0.0 - 0.0, which under the usual IEEE 754 round-ties-to-even mode is 0.0. So it's valid to drop the real part from the repr. In contrast, the real part of -1j is -0.0.

@mdickinson
Copy link
Member

@arigo: Ah, sorry; I think I'm just repeating what you already said.

Yes indeed, eval-ing the repr "-1j" of the result of 0-1j doesn't give back precisely the same result. That's pretty much unavoidable, I'm afraid, and has been discussed in multiple other tracker issues.

For some history on the Python 2 to Python 3 change, see #53257.

For issues related to @arigo's comments, see #70026, #61538, #66738 (almost certainly an incomplete list).

@mdickinson
Copy link
Member

Also FTR: #84450, and @serhiy-storchaka's PR #19593.

@terryjreedy terryjreedy removed the type-bug An unexpected behavior, bug, or error label May 28, 2023
@terryjreedy terryjreedy closed this as not planned Won't fix, can't repro, duplicate, stale May 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir
Projects
None yet
Development

No branches or pull requests

5 participants