[Python-bugs-list] [ python-Bugs-458941 ] Looks like a unary minus bug
noreply@sourceforge.net
noreply@sourceforge.net
Fri, 07 Sep 2001 01:48:20 -0700
Bugs item #458941, was opened at 2001-09-05 16:29
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=458941&group_id=5470
Category: Parser/Compiler
Group: Python 2.2
>Status: Closed
>Resolution: Fixed
Priority: 6
Submitted By: Tim Peters (tim_one)
Assigned to: Tim Peters (tim_one)
Summary: Looks like a unary minus bug
Initial Comment:
The attached program should print the same stuff in
both calls to drive(). It actually prints
Using literals:
0.0
0.0
0.0
0.0
Using computation:
0.0
3.14159265359
0.0
-3.14159265359
on Windows.
The disassembly of driver() suggests the compiler is
optimizing
-0.0
into
0.0, but the sign of a *floating* zero is significant.
This works as expected in 2.1.1; the behavior changed
after that.
----------------------------------------------------------------------
>Comment By: Tim Peters (tim_one)
Date: 2001-09-07 01:48
Message:
Logged In: YES
user_id=31435
Well, it's a very ordinary kind of optimization to do, and
it's good for my coworkers to learn how delicate
optimization really is <0.9 wink>. This kind of thing is
usually done in a peephole pass, although there's so little
difference between parse tree and bytecode perhaps this
counts as a peephole opt.
The primary reason I liked this at first glance was because
it finally squashed an ancient & repeated complaint, that
(on a 32-bit box)
int("-2147483648")
worked fine but
eval("-2147483648")
blew up.
OTOH, Jeremy later solved that in a different way too (by
auto-converting big int literals to longs).
If for nothing else, I think we should leave this (now even
uglier!) code in as a cautionary object lesson for youth
<wink>.
Fixed in Python/compile.c rev 2.222
Quad deuces! Cool.
----------------------------------------------------------------------
Comment By: Guido van Rossum (gvanrossum)
Date: 2001-09-06 02:24
Message:
Logged In: YES
user_id=6380
The com_addconst code was never intended to deal with
anything except positive literals.
I wonder if we are doing ourselves a favor with the
unary-minus optimization? This is the second time we have a
problem in it.
If we want to keep it, making the exception for 0.0 and 0j
makes sense. Back to Tim (or to Fred?)
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2001-09-05 21:45
Message:
Logged In: YES
user_id=31435
Reassigned to Guido for pondering. The unary minus
optimization doesn't appear to be the true cause here, but
rather unmasked a different problem: com_addconst uses a
dict to map (value, type) pairs to consts, and +0.0
compares equal to -0.0. Thus in the test case, compilation
of the tuple
(+0.0, -0.0)
finds +0.0 first, and despite that "-0.0" is correctly
converted to a negative 0 on my box, add_const thinks it's
the same thing: *all* literal float zeroes are treated
like +0.0 just because +0.0 was the first one added to the
consts.
If I change the tuple to
(-0.0, +0.0)
instead, then all literal 0.0 thingies get treated like
minus 0 instead, and the test case prints 4 instances of -
pi (instead of 4 instances of 0).
A sufficient hack to hide this again may be to disable the
unary minus optimization when the NUMBER is a float or
imaginary zero.
----------------------------------------------------------------------
Comment By: Skip Montanaro (montanaro)
Date: 2001-09-05 19:50
Message:
Logged In: YES
user_id=44345
>From the checkin comments, it looks like v 2.216 of
Python/compile.c is the culprit. Getting rid of
com_invert_constant and reverting com_factor to the version
from 2.215 fixes the problem. Looks like it was strictly an
optimization, so it can probably be safely removed.
----------------------------------------------------------------------
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=458941&group_id=5470