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.

Title: 0.0 and -0.0 end up referring to the same object
Type: behavior Stage:
Components: Interpreter Core Versions: Python 2.5
Status: closed Resolution: duplicate
Dependencies: Superseder: fix a bug mixing up 0.0 and-0.0
View: 1678668
Assigned To: Nosy List: christian.heimes, georg.brandl, nnorwitz, rhettinger, swfiua
Priority: normal Keywords:

Created on 2007-05-31 15:27 by swfiua, last changed 2022-04-11 14:56 by admin. This issue is now closed.

File name Uploaded Description Edit swfiua, 2007-05-31 15:27
Messages (6)
msg32152 - (view) Author: Johnnyg (swfiua) Date: 2007-05-31 15:27
I am not really sure whether this is a bug or a feature.

The attached code attempts to demonstrate the problem.

I had some code that was trying to change -0.0 to 0.0 so that the accountants I work with don't panic.

The code was something like this:

if n == -0.0:
    n = 0.0

Regardless of whether n is -0.0 or 0.0 the test passes (which is good).

However after the assignment n is actually -0.0

It looks like python is creating a single object for both -0.0 and 0.0.

Whichever appears first within the local scope seems to be the value that actually gets stored.

Eg changing the code to 

if n == 0.0:
    n = 0.0

gets me the behaviour I wanted.
msg32153 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2007-06-01 05:49
This is a regression from 2.4.  This seems to always have been undefined behaviour.  It looks like it was the result of the compiler changes (code is the same in both versions, but co_consts is diff):

Python 2.4.4c1 (#2, Oct 11 2006, 20:00:03) 
>>> def r(n):
...   if n == -0.0: n = 0.0
...   return n
>>> r.func_code.co_consts
(None, 0.0)

Python 2.6a0 (trunk, May 30 2007, 21:02:18) 
>>> def r(n):
...  if n == -0.0: n = 0.0
...  return n
>>> r.func_code.co_consts
(None, -0.0)
msg32154 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2007-06-03 06:50
I don't see an easy way to make this a defined behavior.

FWIW, the OP's code suggests that it makes a more specific test than it does (since -0.0 == 0.0) so the test succeed when n is either -0.0 or 0.0.  A quick fix in his code would be to eliminate the -0.0 from the code.  

def r(n):
    if n == 0.0:
        return 0.0
    return n

or more succinctly:

def r(n):
    return n or 0.0
msg32155 - (view) Author: Johnnyg (swfiua) Date: 2007-06-05 10:52
I'm happy to flag this as undefined behaviour.

I have worked around it in my code, the only issue is that the code is brittle, since I think it relies on the scope of constants -- I'm guessing that is what has changed between 2.4 and 2.5 and could well change in the future.

msg32156 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2007-06-05 14:07
See also patch #1678668.
msg59796 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2008-01-12 05:19
I mark this bug as duplicate of #1678668. They are both about the same
Date User Action Args
2022-04-11 14:56:24adminsetgithub: 45018
2008-01-12 05:19:02christian.heimessetstatus: open -> closed
superseder: fix a bug mixing up 0.0 and-0.0
messages: + msg59796
resolution: duplicate
nosy: + christian.heimes
type: behavior
2007-05-31 15:27:32swfiuacreate