473,842 Members | 1,585 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Signed zeros: is this a bug?

I get the following behaviour on Python 2.5 (OS X 10.4.8 on PowerPC,
in case it's relevant.)
>>x, y = 0.0, -0.0
x, y
(0.0, 0.0)
>>x, y = -0.0, 0.0
x, y
(-0.0, -0.0)

I would have expected y to be -0.0 in the first case, and 0.0 in the
second. Should the above be considered a bug, or is Python not
expected to honour signs of zeros? I'm working in a situation
involving complex arithmetic where branch cuts, and hence signed
zeros, are important, and it would be handy if the above code could be
relied upon to do the right thing.

Mark

Mar 11 '07 #1
38 2312
On Mar 11, 9:31 am, "Mark Dickinson" <dicki...@gmail .comwrote:
I get the following behaviour on Python 2.5 (OS X 10.4.8 on PowerPC,
in case it's relevant.)
>x, y = 0.0, -0.0
x, y
(0.0, 0.0)
>x, y = -0.0, 0.0
x, y

(-0.0, -0.0)

I would have expected y to be -0.0 in the first case, and 0.0 in the
second. Should the above be considered a bug, or is Python not
expected to honour signs of zeros? I'm working in a situation
involving complex arithmetic where branch cuts, and hence signed
zeros, are important, and it would be handy if the above code could be
relied upon to do the right thing.
IIRC, float.__repr__ just does whatever libc does. Have you tried
using printf("%g, %g", 0.0, -0.0) in a C program?

Mar 11 '07 #2
On Sunday 11 March 2007 10:31, Mark Dickinson
wrote:
I get the following behaviour on Python 2.5 (OS
X 10.4.8 on PowerPC, in case it's relevant.)
>x, y = 0.0, -0.0
x, y

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

(-0.0, -0.0)

I would have expected y to be -0.0 in the first
case, and 0.0 in the second. Should the above
be considered a bug, or is Python not expected
to honour signs of zeros? I'm working in a
situation involving complex arithmetic where
branch cuts, and hence signed zeros, are
important, and it would be handy if the above
code could be relied upon to do the right
thing.

Mark


This works for some reason
instead of x,y = -0.0, 0.0
clumpy but the results are right.

x = -0.0
y= 0.0

x,y
(-0.0, 0.0)


jim-on-linux
http:\\inqvista .com



Mar 11 '07 #3

"Dan Bishop" <da*****@yahoo. comwrote in message
news:11******** *************@3 0g2000cwc.googl egroups.com...
| On Mar 11, 9:31 am, "Mark Dickinson" <dicki...@gmail .comwrote:
| I get the following behaviour on Python 2.5 (OS X 10.4.8 on PowerPC,
| in case it's relevant.)
| >
| >x, y = 0.0, -0.0
| >x, y
| (0.0, 0.0)
| >x, y = -0.0, 0.0
| >x, y
| >
| (-0.0, -0.0)
|| IIRC, float.__repr__ just does whatever libc does. Have you tried
| using printf("%g, %g", 0.0, -0.0) in a C program?

Detailed FP behavior like this is system (and yes, libc) dependent. On
WinXP
IDLE 1.1.3
>>x,y = 0.0, -0.0
x,y
(0.0, 0.0)
>>x,y = -0.0, 0.0
x,y
(0.0, 0.0)
>>-0.0
0.0

Terry Jan Reedy

Mar 11 '07 #4
On Mar 11, 12:13 pm, "Terry Reedy" <tjre...@udel.e duwrote:
"Dan Bishop" <danb...@yahoo. comwrote in message

news:11******** *************@3 0g2000cwc.googl egroups.com...
| On Mar 11, 9:31 am, "Mark Dickinson" <dicki...@gmail .comwrote:
| I get the following behaviour on Python 2.5 (OS X 10.4.8 on PowerPC,
| in case it's relevant.)
| >
| >x, y = 0.0, -0.0
| >x, y
| (0.0, 0.0)
| >x, y = -0.0, 0.0
| >x, y
| >
| (-0.0, -0.0)
|| IIRC, float.__repr__ just does whatever libc does. Have you tried
| using printf("%g, %g", 0.0, -0.0) in a C program?

Detailed FP behavior like this is system (and yes, libc) dependent. On
WinXP
IDLE 1.1.3>>x,y = 0.0, -0.0
>x,y
(0.0, 0.0)
>x,y = -0.0, 0.0
x,y
(0.0, 0.0)
>-0.0

0.0

Terry Jan Reedy
Interesting. So on Windows there's probably no hope of what I want to
do working.
But on a platform where the C library does the right thing with signed
zeros, this
behaviour is still a little surprising. I guess what's happening is
that there's
some optimization that avoids creating two separate float objects for
a float literal
that appears twice, and that optimization doesn't see the difference
between 0. and -0.
>>x, y = 0., -0.
id(x) == id(y)
True

jim-on-linux's solution works in the interpreter, but not in a script,
presumably because we've got file-wide optimization rather than
line-by-line optimization.

#test.py
x = -0.0
y = 0.0
print x, y
#end test.py
>>import test
-0.0 -0.0

Mark

Mar 11 '07 #5
"Mark Dickinson" <di******@gmail .comwrote:
I guess what's happening is that there's some optimization that avoids
creating two separate float objects for a float literal that appears
twice, and that optimization doesn't see the difference between 0. and
-0.
Don't guess. Test.
>>def f():
x = 0.0
y = -0.0
return x, y
>>dis.dis(f)
2 0 LOAD_CONST 1 (0.0)
3 STORE_FAST 0 (x)

3 6 LOAD_CONST 1 (0.0)
9 STORE_FAST 1 (y)

4 12 LOAD_FAST 0 (x)
15 LOAD_FAST 1 (y)
18 BUILD_TUPLE 2
21 RETURN_VALUE

Yes. Just the one constant there.
Tim Peters wrote in
http://blog.gmane.org/gmane.comp.pyt.../day=20050409:
All Python behavior in the presence of a NaN, infinity, or signed zero
is a platform-dependent accident. This is because C89 has no such
concepts, and Python is written to the C89 standard. It's not easy to
fix across all platforms (because there is no portable way to do so in
standard C), although it may be reasonably easy to fix if all anyone
cares about is gcc and MSVC (every platform C compiler has its own set
of gimmicks for "dealing with" these things).
Mar 11 '07 #6
Mark Dickinson <di******@gmail .comwrote:
I get the following behaviour on Python 2.5 (OS X 10.4.8 on PowerPC,
in case it's relevant.)
>x, y = 0.0, -0.0
x, y
(0.0, 0.0)
>x, y = -0.0, 0.0
x, y
(-0.0, -0.0)

I would have expected y to be -0.0 in the first case, and 0.0 in the
second. Should the above be considered a bug, or is Python not
expected to honour signs of zeros? I'm working in a situation
involving complex arithmetic where branch cuts, and hence signed
zeros, are important, and it would be handy if the above code could be
relied upon to do the right thing.
Looks to me like you've found a bug with the parser/compiler:
>>c=compile('-0.0,0.0', 'eval', 'eval')
eval(c)
(-0.0, -0.0)
>>dis.dis(c)
1 0 LOAD_CONST 1 ((-0.0, -0.0))
3 RETURN_VALUE

Similar problems appear in parsing display forms of lists and dicts and
calls to functions with constant arguments (among which a constant 0.0
and a constant -0.0) -- and more generally when both constants -0.0 and
0.0 appear within the same "unit of compilation" (expression, function,
....) as for example in:
>>def f():
.... a = -0.0
.... return a, 0.0
....
>>f()
(-0.0, -0.0)
>>>
Why I think it has specifically to do with parsing/compiling, e.g.:
>>{23:-0.0, 45:0.0}
{45: -0.0, 23: -0.0}
>>x=0.0
y=-0.0
{23:x, 45:y}
{45: -0.0, 23: 0.0}
>>>
so there appears to be no problem once the 0.0 and -0.0 values come from
variables or the like -- only if they're both from constants within the
same "unit of compilation". Indeed, if you put the code above in a
function, rather than in separate entries to the toplevel
interpreter...:
>>def g():
.... x = 0.0
.... y = -0.0
.... return {23:x, 45:y}
....
>>g()
{45: 0.0, 23: 0.0}
>>>
....the bug surfaces again. Looks a bit like the result of a slightly
errant "peephole optimizer" pass which tries to roll multiple
occurrences of "the same constant" within the same codeobject into a
single one, and consider two immutables a "multiple occurrence" if
they're == to each other (as, indeed, 0.0 and -0.0 must be).

The Python-coded compiler package does NOT give the problem:
>>compiler.comp ile('-0.0,0.0','zap', 'eval')
<code object <expressionat 0x70068, file "zap", line 1>
>>dis.dis(_)
1 0 LOAD_CONST 1 (0.0)
3 UNARY_NEGATIVE
4 LOAD_CONST 1 (0.0)
7 BUILD_TUPLE 2
10 RETURN_VALUE

....presumably because it doesn't do peephole optimization (nor any other
kind of optimization).

Unfortunately I've never really looked in depth into these parts of
Python so I can't help much; however, if you open a bug at
<http://sourceforge.net/tracker/?group_id=5470I think you stand a good
chance of eventually seeing it fixed in 2.5.x for some x.
Python/peephole.c does appear to be taking some care in constant
folding:

192 case UNARY_NEGATIVE:
193 /* Preserve the sign of -0.0 */
194 if (PyObject_IsTru e(v) == 1)
195 newconst = PyNumber_Negati ve(v);

so I suspect the problem is elsewhere, but I can't find it yet.
Alex
In the meantime, I hope that some available workarounds for the bug are
clear from this discussion: avoid using multiple constants in a single
compilation unit where one is 0.0 and another is -0.0, or, if you really
can't avoid that, perhaps use compiler.compil e to explicitly build the
bytecode you need.

Mar 11 '07 #7
On Mar 11, 1:21 pm, Duncan Booth <duncan.bo...@i nvalid.invalidw rote:
Tim Peters wrote inhttp://blog.gmane.org/gmane.comp.pyth on.devel/day=20050409:
All Python behavior in the presence of a NaN, infinity, or signed zero
is a platform-dependent accident. This is because C89 has no such
concepts, and Python is written to the C89 standard. It's not easy to
fix across all platforms (because there is no portable way to do so in
standard C), although it may be reasonably easy to fix if all anyone
cares about is gcc and MSVC (every platform C compiler has its own set
of gimmicks for "dealing with" these things).
Understood. Platform dependent is fine. But does this really excuse
results
like the following?
>>from math import atan2
x = -0.; print atan2(0., -1.)
-3.14159265359
>>print atan2(0., -1.)
3.14159265359

Mark

Mar 11 '07 #8
Duncan Booth <du**********@i nvalid.invalidw rote:
"Mark Dickinson" <di******@gmail .comwrote:
I guess what's happening is that there's some optimization that avoids
creating two separate float objects for a float literal that appears
twice, and that optimization doesn't see the difference between 0. and
-0.

Don't guess. Test.
>def f():
x = 0.0
y = -0.0
return x, y
>dis.dis(f)
2 0 LOAD_CONST 1 (0.0)
3 STORE_FAST 0 (x)

3 6 LOAD_CONST 1 (0.0)
9 STORE_FAST 1 (y)

4 12 LOAD_FAST 0 (x)
15 LOAD_FAST 1 (y)
18 BUILD_TUPLE 2
21 RETURN_VALUE

Yes. Just the one constant there.
And yet, as I wrote in a parallel post (the result of quite some
exploration), Python/peephole.c takes specific precautions against
improperly "constant folding" for the unary-minus of 0.0 -- the
collapsing of 0.0 and -0.0 into the "same" constant must happen
elsewhere (I haven't found out where, yet) and doesn't happen in the
Python-coded compiler module. So (on platforms where the underlying C
libraries do the right thing) I think this specific "overzealou s
constant folding" must be considered a small bug -- and should be easy
to fix (by specialcasing -0.0 like Python/peephole.c does) if I could
but find out where in the Python sources the folding is happening...
Alex
Mar 11 '07 #9
On Mar 11, 1:26 pm, a...@mac.com (Alex Martelli) wrote:
[Long analysis of probable cause of the problem]
Thank you for this. I was suspecting something along these lines,
but I don't yet know my way around the source well enough to figure
out where the problem was coming from.
In the meantime, I hope that some available workarounds for the bug are
clear from this discussion: avoid using multiple constants in a single
compilation unit where one is 0.0 and another is -0.0, or, if you really
can't avoid that, perhaps use compiler.compil e to explicitly build the
bytecode you need.
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)

Mark

Mar 11 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
2747
by: TheTeapot | last post by:
Hi all, Here's a puzzle: // Say I have an array of numbers set up like so: $arr = array(15,16,17,100,121,1000); // How can I create a function so that I can use it like so: addleadingzeros_arr($arr); // and have the output look like:
5
11521
by: samik_tanik | last post by:
I need to export a datagrid to Excel. I could did this. But, also need to keep the leading zeros in the data. How can I acheive this? Any help would be appreciated. -- Thanking you in anticipation, Regards,
4
2668
by: Ken Tough | last post by:
Seems like a simple thing to find out, but I'm struggling. I have googled, but everything I find is about implicit conversion, not explicit. Is this implementation-specific, or does ANSI/ISO lay out what should happen for: -------------------------- signed char sc; unsigned char uc;
2
1602
by: Teep | last post by:
I have a simple text box called txtrefnum, if the user enters a number length less than 9 characters long than I need to have lead zeros added to it. Does anyone know how to do this? I couldn't find anything online on the subject... <asp:TextBox id="txtRefNum" runat="server"></asp:TextBox> I thought I could use a validator for the process and make the user add the zeros, but of course that is a big no-no! Please help!!
6
1417
by: TN Bella | last post by:
I have a simple text box called txtrefnum, if the user enters a number length less than 9 characters long than I need to have lead zeros added to it. Does anyone know how to do this? I couldn't find anything online on the subject... <asp:TextBox id="txtRefNum" runat="server"></asp:TextBox> I thought I could use a validator for the process and make the user add the zeros, but of course that is a big no-no! Please help!!
15
20106
by: Bob | last post by:
I'm about to convert to string and use regex, but I thought there must be something I'm missing here that already exists. Bob
18
1760
by: Susan Rice | last post by:
I'm comparing characters via return(str1 - str2); and I'm having problems with 8-bit characters being treated as signed instead of unsigned integers. The disassembly is using movsx eax,byte ptr to load my character in to EAX register. I need it to use movzx.
6
7771
by: JimmyKoolPantz | last post by:
Task: Customer wants a script of the data that was processed in a "CSV" file. Problem: Zip-Code leading zeros are dropped Basically we have a client that has requested a custom script for each file that he has us process. He wants this in a Comma Delimited Format.
3
9926
by: ManuelValdez | last post by:
Hello everybody! I need your valuable help to get an Excel macro to delete the single zeros only and no the zeros containing numbers like 360, 90, etc., because if I chose the search and replace in the Edit option, then all the zeros containing the numbers 360, 90, 502, etc. will be deleted. Some nice person helped me with the following code to delete the zeros: Selection.Replace What:="0", Replacement:="" , but unfortunately this code...
0
9715
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10945
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10612
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10672
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9453
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5696
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4499
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4089
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3145
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.