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

Bogus parsing of negative zeros in complex literals #66738

Closed
pitrou opened this issue Oct 3, 2014 · 10 comments
Closed

Bogus parsing of negative zeros in complex literals #66738

pitrou opened this issue Oct 3, 2014 · 10 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@pitrou
Copy link
Member

pitrou commented Oct 3, 2014

BPO 22548
Nosy @mdickinson, @pitrou, @benjaminp, @serhiy-storchaka

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:

assignee = None
closed_at = <Date 2014-10-03.17:28:16.030>
created_at = <Date 2014-10-03.17:24:14.483>
labels = ['interpreter-core', 'type-bug', 'invalid']
title = 'Bogus parsing of negative zeros in complex literals'
updated_at = <Date 2020-04-19.08:31:05.260>
user = 'https://github.com/pitrou'

bugs.python.org fields:

activity = <Date 2020-04-19.08:31:05.260>
actor = 'serhiy.storchaka'
assignee = 'none'
closed = True
closed_date = <Date 2014-10-03.17:28:16.030>
closer = 'mark.dickinson'
components = ['Interpreter Core']
creation = <Date 2014-10-03.17:24:14.483>
creator = 'pitrou'
dependencies = []
files = []
hgrepos = []
issue_num = 22548
keywords = []
message_count = 10.0
messages = ['228343', '228345', '228346', '228347', '228351', '228352', '228353', '228354', '228356', '228360']
nosy_count = 4.0
nosy_names = ['mark.dickinson', 'pitrou', 'benjamin.peterson', 'serhiy.storchaka']
pr_nums = []
priority = 'low'
resolution = 'not a bug'
stage = None
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue22548'
versions = ['Python 3.5']

@pitrou
Copy link
Member Author

pitrou commented Oct 3, 2014

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

@pitrou pitrou added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels Oct 3, 2014
@mdickinson
Copy link
Member

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.

@mdickinson
Copy link
Member

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.

@mdickinson
Copy link
Member

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.

@pitrou
Copy link
Member Author

pitrou commented Oct 3, 2014

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

@mdickinson
Copy link
Member

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.

@pitrou
Copy link
Member Author

pitrou commented Oct 3, 2014

Yes, the last part is ok. It's the preceding parts that are a bit surprising.

@pitrou
Copy link
Member Author

pitrou commented Oct 3, 2014

Oops, I get it now. Sorry.

@mdickinson
Copy link
Member

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.

@mdickinson
Copy link
Member

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
"""

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

2 participants