[ python-Bugs-1678380 ] 0.0 and -0.0 identified, with surprising results

SourceForge.net noreply at sourceforge.net
Mon Apr 2 21:03:18 CEST 2007


Bugs item #1678380, was opened at 2007-03-11 12:16
Message generated for change (Settings changed) made by rhettinger
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1678380&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Python Interpreter Core
Group: None
Status: Open
Resolution: Accepted
>Priority: 6
Private: No
Submitted By: Mark Dickinson (marketdickinson)
Assigned to: Alex Martelli (aleax)
Summary: 0.0 and -0.0 identified, with surprising results

Initial Comment:
The identification of -0.0 and 0.0 in scripts leads to some surprising
results.  In particular, code that behaves one way in the interpreter can behave differently in a script.  For example:

Python 2.6a0 (trunk:54183M, Mar  6 2007, 20:16:00) 
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import atan2;
>>> x = -0.
>>> y = 0.
>>> print atan2(y, -1.)
3.14159265359

But:

>>> exec("from math import atan2; x = -0.; y = 0.; print atan2(y, -1.)")
-3.14159265359

A simpler example:

>>> x, y = -0., 0.
>>> x, y
(-0.0, -0.0)
>>> id(x) == id(y)
True

But:

>>> x = -0.
>>> y = 0.
>>> x, y
(-0.0, 0.0)

This occurs both on SuSE Linux 9.3/i686 and on OS X 10.4.8/PowerPC.


----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2007-04-02 14:02

Message:
Logged In: YES 
user_id=80475
Originator: NO

The distinction between +0.0 and -0.0 was important to Tim for get the
branch cuts to work correctly.  That was the reason for the special-casing
in earlier versions in pre-ast versions of compile.c and in the peephole
optimizer.

Alex's patch looks correct.  It should go into Py2.5.1.

----------------------------------------------------------------------

Comment By: Alex Martelli (aleax)
Date: 2007-03-12 09:57

Message:
Logged In: YES 
user_id=60314
Originator: NO

and yet, peephole.c does specialcase -0 (with a comment and all!-)
avoiding constant-folding optimization for it -- making things work fine in
Python 2.4.x for high enough x -- it's just that peephole.c's efforts are
defeated by a similar optimization applied without specialcase checking in
ast.c in Python 2.5.  This is inconsistent: it makes no sense to take SOME
of the precautions needed to avoid an issue but not ALL of them, since this
makes the issue appear anyway, so those precautions that ARE taken are
there for no purpose (except a miniscule slowdown and enlargement of the
interpreter:-).  Either we save those few lines of code in peephole.c or
add the few lines to ast.c that I suggest in my patch 1678668 -- the
current situation makes no sense.

----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2007-03-12 04:04

Message:
Logged In: YES 
user_id=21627
Originator: NO

I also expressed myself badly. I not only meant that programs should not
rely on +0 and -0 being different things across platforms, but that they
should also not rely on them being either always different or always the
same in a single program. If Python would randomly chose to interpret +0 as
-0, or would do so for every third occurence, I still couldn't see a
problem.

----------------------------------------------------------------------

Comment By: Alex Martelli (aleax)
Date: 2007-03-11 20:54

Message:
Logged In: YES 
user_id=60314
Originator: NO

Oops,sorry, I meant patch 1678668 (copy-and-pasted the wrong ID:-).

Alex


----------------------------------------------------------------------

Comment By: Alex Martelli (aleax)
Date: 2007-03-11 20:51

Message:
Logged In: YES 
user_id=60314
Originator: NO

Also see my patch 1678380 which fixes this bug (and checks for it in a new
unittest).


----------------------------------------------------------------------

Comment By: Mark Dickinson (marketdickinson)
Date: 2007-03-11 20:15

Message:
Logged In: YES 
user_id=703403
Originator: YES

I expressed myself badly.  I apologise.  This really isn't about +0. and
-0. 
being different, or not.  I'm perfectly comfortable with the idea that +0.

and -0. may or may not be distinguishable on any given platform.

The surprise is the other way around: two *identical* calls to atan(0.,
-1.)
(or to repr(0.) for that matter) give *different* results, depending
solely 
on whether a -0. literal has appeared earlier on in the code unit being
compiled.

So if the first float zero literal encountered in a source file just
happens to be a
-0. rather than a 0., the meaning of str(0.) later on suddenly becomes
"-0.0"
rather than "0.0".  I'd like to be able to rely on str(0.) meaning "0.0"
without
having to worry about whether there might be a -0. literal appearing in
some
faraway and otherwise completely irrelevant portion of the file.


----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2007-03-11 17:27

Message:
Logged In: YES 
user_id=21627
Originator: NO

marketdickinson, you should ask this question (is this really acceptable)
on python-dev. I find it perfectly acceptable. No program should rely on -0
and +0 being two different things (and thus also not relying on atan2
giving two different results).

----------------------------------------------------------------------

Comment By: Gabriel Genellina (gagenellina)
Date: 2007-03-11 15:10

Message:
Logged In: YES 
user_id=479790
Originator: NO

It appears to be a problem in the way compile.c handles literals.
See http://mail.python.org/pipermail/python-list/2007-March/430302.html

----------------------------------------------------------------------

Comment By: Mark Dickinson (marketdickinson)
Date: 2007-03-11 14:21

Message:
Logged In: YES 
user_id=703403
Originator: YES

May I beg for reconsideration.
Is the following really considered acceptable?

>>> x = -0.; atan2(0., -1)
-3.1415926535897931
>>> x = -(0.); atan2(0., -1)
3.1415926535897931
>>> atan2(0., -1)
3.1415926535897931

A single x = -0. at the start of a script can have
side effects several hundred lines later, even when
the variable x is never referred to again.  I guess
the advice should be:  "To avoid surprises, -0. should
never appear in any script."

----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2007-03-11 13:35

Message:
Logged In: YES 
user_id=21627
Originator: NO

This is not a bug, at least not one that will be fixed. Details of the
floating-point can vary across platforms, and they may behave in suprising
ways in various contexts. Users shouldn't rely on Python differentiating
between -0 and +0.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1678380&group_id=5470


More information about the Python-bugs-list mailing list