classification
Title: 0.0 and -0.0 end up referring to the same object
Type: behavior
Components: Interpreter Core Versions: Python 2.5
process
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 2008-01-12 05:19 by christian.heimes.

Files
File name Uploaded Description Edit Remove
p25.py swfiua, 2007-05-31 15:27
Messages
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) 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) 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.

John
msg32156 (view) Author: Georg Brandl (georg.brandl) Date: 2007-06-05 14:07
See also patch #1678668.
msg59796 (view) Author: Christian Heimes (christian.heimes) Date: 2008-01-12 05:19
I mark this bug as duplicate of #1678668. They are both about the same
issue.
History
Date User Action Args
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