473,569 Members | 2,872 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 2272
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
2732
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
11491
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
2647
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
1582
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...
6
1407
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...
15
20076
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
1737
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
7740
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
9912
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...
0
7703
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7619
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...
0
8138
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...
0
7983
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6290
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...
0
3662
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...
0
3651
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2118
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
0
950
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...

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.