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
negative zero components are ignored in complex number literals #70026
Comments
Although -0.0 and +0.0 compare as equal using the == operator, they are distinct floating point numbers and in some cases behave differently. (See more information on the wikipedia article "Signed zero".) The distinction between +0.0 and -0.0 is most important in complex arithmetic, for example it is conventional and useful that sqrt(-1+0i) ==> +i and sqrt(-1-0i) ==> -i. Python currently allows the floating point number -0.0 to be entered as a literal: >>> -0.0
-0.0 Complex floating point numbers in python also can hold negative zero components, as shown in their repr() >>> -(1+0j)
(-1-0j) However they cannot be input directly as literals; it is currently necessary to use the above construction. Unfortunately the output of the repr() cannot be used as a string literal to obtain the same number: >>> (-1-0j)
(-1+0j) except, in contrast: >>> complex('-1-0j')
(-1-0j) The literal -1-0j should yield a complex number with negative zero imaginary part. Note also that complex literals with negative zero real parts have the same bug, e.g. -0+1j is not the same as -(0-1j) |
You should use complex(a, b) to have a reliable behaviour. Python parse doesn't see "-1-0j" as a complex literal, but as (-1)-(0j): int-complex. Example with the AST output: >>> ast.dump(ast.parse('-1-0j'))
'Module(body=[Expr(value=BinOp(left=UnaryOp(op=USub(), operand=Num(n=1)), op=Sub(), right=Num(n=0j)))])' It looks like complex has the same behaviour than float: >>> x=-0.0; x=0+x; x.real
0.0
>>> x=-0.0; x=0-x; x.real
0.0
>>> x=complex(0.0, -0.0); x=0+x; (x.real, x.imag)
(0.0, 0.0)
>>> x=complex(0.0, -0.0); x=0-x; (x.real, x.imag)
(0.0, 0.0) zero sign is lost on int+complex, int-complex, int+complex, int-complex. |
Good point, it is doing (int-complex), observe also the following pecularities: >>> -0 - 0j
0j
>>> -0. - 0j
(-0+0j)
>>> -0j
-0j
>>> 0-0j
0j
>>> -(0j)
(-0-0j)
>>> 0.+(-0j)
0j Does this mean the bug is in repr() ? As I understand the output of repr() is supposed to be something that can evaluated to recreate the same object. However I am unsure whether it would be nicer if repr() were to yield 'complex(-0.,-0.)' or '-(-0.+0j)'. |
This is something that comes up repeatedly on the bug tracker. There's no bug here in the complex type or the repr. What there *is* is a limitation resulting from the fact that Python doesn't have *imaginary* literals, only *complex* literals. So in: -1-0j the 0j is already a complex number with both real and imaginary parts equal to 0.0. Then -1 gets promoted to a complex number with real part -1 and imaginary part 0.0. And now you're doing: complex(-1.0, 0.0) - complex(0.0, 0.0) which naturally gives an imaginary part of +0.0 rather than 0.0. You'll see the same issue in C: there was an attempt to fix it in C99 by introducing Imaginary types, but those Imaginary types haven't been widely adopted. The most recent reincarnation of the C standard finally introduces a macro that lets you instantiate a complex number in terms of its real and imaginary components (instead of doing real_part + imag_part * I); this is something that Python already has in the form of the complex constructor. Closing as not a bug. |
Right, but that's an ideal that's not always achieved in practice. If I had my druthers, I'd 'fix' the repr of the complex object to return something that's written in terms of the constructor (for example, "complex(2.3, -0.0)"). I don't think that's a reasonable change from the POV of backwards compatibility though. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: