Signed zeros: is this a bug?

Tim Peters tim.one at comcast.net
Sun Mar 11 17:15:59 EDT 2007


[attribution lost]
...
>>> Yup: the workaround seems to be as simple as replacing all 
occurrences
>>> of -0.0 with -(0.0).  I'm embarrassed that I didn't figure this out
>>> sooner.
>>> 
>>> >>> x, y = -(0.0), 0.0
>>> >>> x, y
>>> (-0.0, 0.0)

[Alex Martelli]
>> Glad it works for you, but it's the kind of workaround that could
>> break with any minor tweak/optimization to the compiler...
>> very fragile:-(.

[also Alex]
> OTOH, Python 2.4 works just fine...:
>
> Python 2.4.3 (#1, Apr  7 2006, 10:54:33) 
> [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
> Type "help", "copyright", "credits" or "license" for more information.
> >>> 0.0,-0.0
> (0.0, -0.0)
> >>> -0.0,0.0
> (-0.0, 0.0)
>
> so it seems to be very specifically a 2.5 problem.

It's a bug that keeps resurfacing, probably because there's no portable 
way to test that it stays fixed :-( (it's not an accident that the OP 
relied on atan2 to distinguish +0.0 from -0.0!  they act the same in 
/almost/ all contexts).

Python's grammar doesn't have negative numeric literals.  Instead

    "-" CONSTANT_LITERAL

looks like unary minus applied to the non-negative CONSTANT_LITERAL.  
All early versions of Python worked that way too.

The first time the +/- 0.0 bug occurred is when the front end was 
changed to act as if

    "-" CONSTANT_LITERAL

were a literal in its own right, and then that +0.0 == -0.0 caused the 
first instance of either in a compilation unit to be used as the value 
for all instances of both throughout the compilation unit.  That was 
fixed by refusing to apply the optimimization if the value of 
CONSTANT_LITERAL was a float that compared equal to 0.0.

2.5 introduced a new front end and more ambitious constant-folding, and 
I expect the bug showed up again due to one of those.

Note:  printing the value of a float 0 may not reveal its sign.  IIRC, 
glibc's float-to-string routines do display the sign of 0, but 
Microsoft's do not.  However, atan2() is sensitive to the sign under 
both glibm and Microsoft's libm equivalent.



More information about the Python-list mailing list