Re: Signed zeros: is this a bug?

2007-03-13 Thread Hendrik van Rooyen
 Paddy [EMAIL PROTECTED] wrote

 
 Hey, I'm still learnin'. Sweet!
 
contrary to popular belief, the answer to life,
the universe, happiness and everything is
not 42, but the above.

- Hendrik

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-12 Thread Ben Finney
[EMAIL PROTECTED] (Alex Martelli) writes:

 This is not trivial to fix cleanly...:-(.  compiler_add_o would have
 to test is the object I'm storing -0.0 (I don't even know how to
 do that in portable C...) and then do some kludge -- e.g. use as the
 key into the dict (-0.0, 0) instead of (-0.0, float) for this one
 special case.

Another way, which avoids making this decision, is to always store the
sign *and* value of the number as part of the key. I don't know if
that tradeoff is the right one though.

-- 
 \   Our products just aren't engineered for security.  -- Brian |
  `\ Valentine, senior vice-president of Microsoft Windows |
_o__)  development |
Ben Finney

-- 
http://mail.python.org/mailman/listinfo/python-list


Signed zeros: is this a bug?

2007-03-11 Thread Mark Dickinson
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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Dan Bishop
On Mar 11, 9:31 am, Mark Dickinson [EMAIL PROTECTED] 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.

IIRC, float.__repr__ just does whatever libc does.  Have you tried
using printf(%g, %g, 0.0, -0.0) in a C program?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread jim-on-linux
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







-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Terry Reedy

Dan Bishop [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
| On Mar 11, 9:31 am, Mark Dickinson [EMAIL PROTECTED] 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)
|| 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



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Mark Dickinson
On Mar 11, 12:13 pm, Terry Reedy [EMAIL PROTECTED] wrote:
 Dan Bishop [EMAIL PROTECTED] wrote in message

 news:[EMAIL PROTECTED]
 | On Mar 11, 9:31 am, Mark Dickinson [EMAIL PROTECTED] 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)
 || 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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Duncan Booth
Mark Dickinson [EMAIL PROTECTED] wrote:

 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_FAST0 (x)
 15 LOAD_FAST1 (y)
 18 BUILD_TUPLE  2
 21 RETURN_VALUE

Yes. Just the one constant there.


Tim Peters wrote in 
http://blog.gmane.org/gmane.comp.python.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).

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Alex Martelli
Mark Dickinson [EMAIL PROTECTED] 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.

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.compile('-0.0,0.0','zap','eval')
code object expression at 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=5470 I 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_IsTrue(v) == 1)
195 newconst = PyNumber_Negative(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.compile to explicitly build the
bytecode you need.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Mark Dickinson
On Mar 11, 1:21 pm, Duncan Booth [EMAIL PROTECTED] wrote:
 Tim Peters wrote inhttp://blog.gmane.org/gmane.comp.python.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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Alex Martelli
Duncan Booth [EMAIL PROTECTED] wrote:

 Mark Dickinson [EMAIL PROTECTED] wrote:
 
  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_FAST0 (x)
  15 LOAD_FAST1 (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 overzealous
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
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Mark Dickinson
On Mar 11, 1:26 pm, [EMAIL PROTECTED] (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.compile 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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread jim-on-linux

#

 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


This is the only way I could make this work in a 
script.

from decimal import Decimal

x = Decimal( -0.0)
y= Decimal(0.0)
print x,y


x = Decimal( 0.0)
y= Decimal(-0.0)
print x,y



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












-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Alex Martelli
Mark Dickinson [EMAIL PROTECTED] wrote:

 On Mar 11, 1:26 pm, [EMAIL PROTECTED] (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.

The parser/compiler/etc are unfortunately some of the hardest parts of
the sources -- I'm not all that familiar with that part myself, which is
why it took me quite some digging.


  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.compile 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)

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:-(.

I think i found the cause of the bug, BTW.  The collection of constants
in a code object is built in Python/compile.c and it's built as a
dictionary, field u_consts in struct compiler_unit.  The visitor for
an expression that is a number is (in a case statement)

case Num_kind:
ADDOP_O(c, LOAD_CONST, e-v.Num.n, consts);
break;

(line 2947 of compile.c in Python's current sources from svn). ADDOP_O
just calls compiler_addop_o, which in turn does compiler_add_o before
adding the opcode (LOAD_CONST)

compiler_add_o (at lines 903-933) is used for all of the temporary
dictionaries in compiler_unit; a Python equivalent, basically, would be:

def eqv_cao(somedict, someobj):
# make sure types aren't coerced, e.g. int and long
t = someobj, type(someobj)
if t in somedict:
return somedict[t]
somedict[t] = index = len(somedict)
return index

a simple and fast way to provide a distinct numeric index (0 and up) to
each of a bunch of (hashable) objects.

Alas, here is the problem...: 0.0 and -0.0 are NOT separate as dict
keys!  They are == to each other.  So are 0, 0L, and 0+j0, but the
compiler smartly distinguishes these cases by using (obj, type) as the
key (the *types* are distinguished, even though the *values*) are; this
doesn't help with 0.0 and -0.0 since both have type float.

So, the first occurrence of either 0.0 or -0.0 in the compilation unit
ends up in the table of constants, and every other occurrence of either
value later in the unit is mapped to that one constant value:-(

This is not trivial to fix cleanly...:-(.  compiler_add_o would have to
test is the object I'm storing -0.0 (I don't even know how to do that
in portable C...) and then do some kludge -- e.g. use as the key into
the dict (-0.0, 0) instead of (-0.0, float) for this one special case.
(I think the table of constants would still be emitted OK, since the
type part of the key is elided anyway in that table as placed in the
bytecode).  Or maybe we should give up ever storing -0.0 in the tables
of constant and ALWAYS have 0.0, unary-minus wherever it appears (that
would presumably require working on the AST-to-bytecode visitors that
currently work ever-so-slightly-differently for this specific
troublespot in the C-coded version vs the Python-coded one...).

If you know the proper way to test for -0.0 in portable C code (or some
feature macro to use in a #if to protect nonportable code) I could try
proposing the first of these two solutions as a patch (I'm not going to
keep delving into that AST and visitors much longer...:-), but I suspect
it would be rejected as too tricky [and minisculely slowing down every
compilation] for something that's too much of special case [and Python
does not undertake to support in general anyway].  Still, we can't be
sure unless we try (and maybe somebody can think of a cleaner
workaround...).


Alex
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Alex Martelli
Alex Martelli [EMAIL PROTECTED] wrote:
   ...
  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)
 
 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:-(.

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.


Alex
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Scott David Daniels
Alex Martelli wrote:
 Alas, here is the problem...: 0.0 and -0.0 are NOT separate as dict
 keys!  They are == to each other.  So are 0, 0L, and 0+j0, but the
 compiler smartly distinguishes these cases by using (obj, type) as the
 key (the *types* are distinguished, even though the *values*) are; this
 doesn't help with 0.0 and -0.0 since both have type float
 If you know the proper way to test for -0.0 in portable C code (or some
 feature macro to use in a #if to protect nonportable code) 

Perhaps you could add a type NegativeFloat -- a subtype of float,
and distinguish negative zero from zero that way.  Not saying I know how
in portable C, but 

--Scott David Daniels
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Gabriel Genellina
En Sun, 11 Mar 2007 15:26:01 -0300, Alex Martelli [EMAIL PROTECTED] escribió:

 Or maybe we should give up ever storing -0.0 in the tables
 of constant and ALWAYS have 0.0, unary-minus wherever it appears (that
 would presumably require working on the AST-to-bytecode visitors that
 currently work ever-so-slightly-differently for this specific
 troublespot in the C-coded version vs the Python-coded one...).

I think that way is the less intrusive, doesn't rely on a particular FP  
implementation, and the more likely to be accepted.
Looking at ast.c, the culprit is some optimization in ast_for_factor, line  
1506
 /* If the unary - operator is applied to a constant, don't generate
a UNARY_NEGATIVE opcode.  Just store the approriate value as a
constant.  The peephole optimizer already does something like
this but it doesn't handle the case where the constant is
(sys.maxint - 1).  In that case, we want a PyIntObject, not a
PyLongObject.
 */

After the long if, I would use parsenumber(STR(pnum)) and check the type  
and value of the resulting object; if it's a float and 0.0, skip the  
optimization and continue below as a normal case.
Unfortunately I'm not able to compile and test the code right now, so I  
can't provide an actual patch. (At least, not until tuesday). But I hope  
this simple comment is useful anyway...

(I cannot find peephole.c on the source distribution for Python 2.5, but  
you menctioned it on a previous message, and the comment above refers to  
the peephole optimizer... where is it?)

-- 
Gabriel Genellina

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Mark Dickinson
On Mar 11, 2:59 pm, [EMAIL PROTECTED] (Alex Martelli) wrote:
 [...]
 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.

I've filed a bug report (bug #1678380) and got an impressively
quick response from MvL.  It looks like this is a `won't fix'.
Oh well.

Thanks for all your help.

Mark

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Tim Peters
[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.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Paul Rubin
Tim Peters [EMAIL PROTECTED] writes:
 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.

I hope it does get fixed.  Not having referential transparency in a
basic math function like atan2 is pretty disturbing in a modern
computer language.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Paul Rubin
Dennis Lee Bieber [EMAIL PROTECTED] writes:
   Pardon? What is the right thing with signed zeros... In the last
 30 years I've been on machines that normalize floating zero into a true
 zero (all bits are zero: mantissa, exponent, and sign). This is the
 first time I've even seen a variable output as a negative 0.0!

Most machines these days use IEEE 754 which supports negative zero.

http://en.wikipedia.org/wiki/Negative_zero
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Mark Dickinson
On Mar 11, 5:15 pm, Tim Peters [EMAIL PROTECTED] wrote:
 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).

Not an accident, but not a contrived example either.  I'd rewritten
all the cmath routines (in pure Python) to be more numerically aware
and use the
`correct' (= those recommended by Kahan) branch cuts.  It was in
writing the unit tests for this that the problems above surfaced.

By the way, I don't suppose that anybody would be interested in
a rewritten cmath for Python 2.6?  It wouldn't be hard for me to
rewrite what I already have in C, and add suitable documentation
and tests.

Mark

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Paul Rubin
Mark Dickinson [EMAIL PROTECTED] writes:
 By the way, I don't suppose that anybody would be interested in
 a rewritten cmath for Python 2.6?  It wouldn't be hard for me to
 rewrite what I already have in C, and add suitable documentation
 and tests.

I can't speak for the developers but my personal opinion is that this
is worthwhile.  I'm pretty Common Lisp and Scheme specify the branch
cuts and I believe Java does the same.  That is to help with the
consistency and predicability of program behavior as well as to help
various numerical algorithms.  C has a different goal, which is to be
a semi-portable assembly language, putting priority instead on
minimizing intermediation between the programmer and the machine,
instead of on predicability.  Python should take the approach of the
higher level languages and implement this stuff precisely, instead of
just going along with whatever loose semantics the underlying C
implementation happens to supply.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Paddy
On Mar 11, 9:28 pm, Paul Rubin http://[EMAIL PROTECTED] wrote:
 Dennis Lee Bieber [EMAIL PROTECTED] writes:

 Pardon? What is the right thing with signed zeros... In the last
  30 years I've been on machines that normalize floating zero into a true
  zero (all bits are zero: mantissa, exponent, and sign). This is the
  first time I've even seen a variable output as a negative 0.0!

 Most machines these days use IEEE 754 which supports negative zero.

 http://en.wikipedia.org/wiki/Negative_zero

Isn't negative zero mathematically the same as zero? Isn't -0 just an
artefact of the representation of floating point numbers? Shouldn't
f(0) == f(-0) for all functions f?
I read the wikipedia article about meteorologists using -0 to denote a
negative number rounded to zero for the purposes of binning, i.e. if
you want to tally days with temperature above and below zero, but it
doesn't seem right. You should arrange for any temperature to be in
only one range and record temperatures to their determined accuracy. a
temperature of zero would only be in one bin and if a temperature is
read as -0.2 and th rounding says it should be taken as zero then it
should go in the same bin as any positive reading that is rounded to
zero.
Getting back to Python, shouldn't we strive to remove any distinction?
a zero is a zero regardless of sign and a function like atan returning
one of two different vaues for an argument of zero is actually
mathematically not a bad thing to do?

- Paddy.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Michael Spencer
Gabriel Genellina wrote:

 
 (I cannot find peephole.c on the source distribution for Python 2.5, but  
 you menctioned it on a previous message, and the comment above refers to  
 the peephole optimizer... where is it?)
 

The peephole optimizer is in compile.c - the entry point is optimize_code

BTW, I have written a pure-Python compiler which aims to be functionally 
identical to the Python 2.5 compiler, and is in fact very similar (much closer 
than stdlib.compiler).  It may be helpful in investigating alternative 
workarounds for the -0.0 issue.

http://svn.brownspencer.com/pycompiler/branches/new_ast/

Michael

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Paul Rubin
Paddy [EMAIL PROTECTED] writes:
  Most machines these days use IEEE 754 which supports negative zero.
  http://en.wikipedia.org/wiki/Negative_zero
 
 Isn't negative zero mathematically the same as zero? Isn't -0 just an
 artefact of the representation of floating point numbers? Shouldn't
 f(0) == f(-0) for all functions f?

Not sure what you mean.  Floating point numbers and in particular
IEEE 754 floating point numbers are a set of values and operations
with particular characteristics, that computers happen to implement.
They are not the same thing as the mathematical real numbers.  For
example, there are infinitely many real numbers, but there are only
finitely many 64-bit IEEE floating point numbers (at most 2**64 of
them).  They don't satisfy the same algebraic laws as real numbers.
For example, (1e100 + 1) == 1e100, and as a consequence, (1e100 + 1) -
1e100 == 0, but (1e100 - 1e100) + 1 == 1, so the commutative addition
law doesn't hold.  These are all part of a mesh of interlocking
compromises made in floating point computer arithmetic to approximate
real-number arithmetic with finite-precision values.  At first (i.e.
from the early computer era through the 1970's or so) this stuff was
designed somewhat ad hoc by computer architects, but eventually
serious numerical mathemticians got into the act, figuring out how to
make the best possible choices of these compromises for numerical
computation.  The result was IEEE 754, which resulted in Prof. Kahan
winning the Turing award in 1989.

IEEE 754 specifies that -0 and +0 are separate numbers.  Yes it is an
artifact in the sense of being one of the compromises.  But these
compromises all interact with each other to make the errors cancel in
various numerical algorithms.  The existence of -0 in IEEE 754 is part
of an intricate framework designed very carefully over a long period
by extremely experienced and knowledgeable people who knew what they
were doing.  It's not really wise to mess with it unless you're
planning to undertake a project to redesign computer arithmetic of
similar scope to the IEEE 754 effort.

 Getting back to Python, shouldn't we strive to remove any distinction?
 a zero is a zero regardless of sign and a function like atan returning
 one of two different vaues for an argument of zero is actually
 mathematically not a bad thing to do?

No.  Floating point numbers are not the same as real numbers and they
don't satisfy the same laws.  There have been some proposals
(rejected) for Python to support exact rational arithmetic in addition
to floating point and exact integer arithmetic.  Exact rationals in
Python (if implemented) should behave like mathematical rationals.
But Python floating point arithmetic should follow IEEE 754, at least
when the hardware supports it, which these days is almost always.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread André
On Mar 11, 7:49 pm, Paddy [EMAIL PROTECTED] wrote:

 Isn't negative zero mathematically the same as zero? Isn't -0 just an
 artefact of the representation of floating point numbers? Shouldn't
 f(0) == f(-0) for all functions f?

Read the original post again...  The relevant part is:

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.


You may want to read about branch cuts and complex arithmetics.  I
don't mean this as a putdown - simply as a useful suggestion for you
to read.

André



-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Signed zeros: is this a bug?

2007-03-11 Thread Alex Martelli
Gabriel Genellina [EMAIL PROTECTED] wrote:

 En Sun, 11 Mar 2007 15:26:01 -0300, Alex Martelli [EMAIL PROTECTED] 
 escribió:
 
  Or maybe we should give up ever storing -0.0 in the tables
  of constant and ALWAYS have 0.0, unary-minus wherever it appears (that
  would presumably require working on the AST-to-bytecode visitors that
  currently work ever-so-slightly-differently for this specific
  troublespot in the C-coded version vs the Python-coded one...).
 
 I think that way is the less intrusive, doesn't rely on a particular FP
 implementation, and the more likely to be accepted.
 Looking at ast.c, the culprit is some optimization in ast_for_factor, line
 1506
  /* If the unary - operator is applied to a constant, don't generate
 a UNARY_NEGATIVE opcode.  Just store the approriate value as a
 constant.  The peephole optimizer already does something like
 this but it doesn't handle the case where the constant is
 (sys.maxint - 1).  In that case, we want a PyIntObject, not a
 PyLongObject.
  */
 
 After the long if, I would use parsenumber(STR(pnum)) and check the type
 and value of the resulting object; if it's a float and 0.0, skip the
 optimization and continue below as a normal case.
 Unfortunately I'm not able to compile and test the code right now, so I
 can't provide an actual patch. (At least, not until tuesday). But I hope
 this simple comment is useful anyway...

Yep, it sure might, if I can make time to act on it:-).


 (I cannot find peephole.c on the source distribution for Python 2.5, but
 you menctioned it on a previous message, and the comment above refers to
 the peephole optimizer... where is it?)

http://svn.python.org/view/python/trunk/Python/peephole.c?rev=54086view
=auto

to browse the current version on the trunk.  Right under the Python
toplevel subdirectory in the sources, IOW.


Alex
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Alex Martelli
Alex Martelli [EMAIL PROTECTED] wrote:
   ...
 Yep, it sure might, if I can make time to act on it:-).

...and I did -- patch 1678668 is right there, brand newm at
http://sourceforge.net/tracker/index.php .

I hope it also satisfies the timbot's very reasonable lament about the
bug resurfacing once in a while, since it included one more unittest to
check whether the bug is there (TDD rocks!-). 


Alex
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Alex Martelli
Mark Dickinson [EMAIL PROTECTED] wrote:

 On Mar 11, 2:59 pm, [EMAIL PROTECTED] (Alex Martelli) wrote:
  [...]
  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.
 
 I've filed a bug report (bug #1678380) and got an impressively
 quick response from MvL.  It looks like this is a `won't fix'.
 Oh well.

That bug isn't formally closed yet, and the discussion's going on, we'll
see.  Meanwhile can you try my patch 1678668 just to double check it
does fix everything?  (It's agains the current HEAD of Python's svn).


Alex
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Alex Martelli
Tim Peters [EMAIL PROTECTED] wrote:
   ...
 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 

Please take a look at my patch 1678668, brand new at
http://sourceforge.net/tracker/index.php and as yet unassigned (hint,
hint:-).

I hope it satisfies your very reasonable lament about the bug
resurfacing once in a while, since it included one more unittest to
check whether the bug is there (TDD rocks!-), based exactly on the
behavior of atan2 (only on IEEE-format machines, though).

 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.

Yep, in ast.c's ast_for_factor -- it lacks the specialcasing that
peephole.c does have (and my patch essentially adds it back).

If it's worth specialcasing in peephole.c (and I strongly agree with
Raymond's implicit opinion that it is), it should be just as worth
specialcasing in ast.c, no?-)


Alex
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Alex Martelli
Paul Rubin http://[EMAIL PROTECTED] wrote:

 (rejected) for Python to support exact rational arithmetic in addition
 to floating point and exact integer arithmetic.  Exact rationals in
 Python (if implemented) should behave like mathematical rationals.
 But Python floating point arithmetic should follow IEEE 754, at least
 when the hardware supports it, which these days is almost always.

Incidentally (and I know you know that, Paul, but others interested in
this thread might not) fast exact rational arithmetic (based on the LGPL
library named GMP) is supplied, among other functionality, by module
gmpy, currently found at http://code.google.com/p/gmpy/ (this version is
more recent than the older one at sourceforce, which for some reason
doesn't let me update things right any more).


Alex
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Jorge Godoy
[EMAIL PROTECTED] (Alex Martelli) writes:

 Incidentally (and I know you know that, Paul, but others interested in
 this thread might not) fast exact rational arithmetic (based on the LGPL
 library named GMP) is supplied, among other functionality, by module
 gmpy, currently found at http://code.google.com/p/gmpy/ (this version is
 more recent than the older one at sourceforce, which for some reason
 doesn't let me update things right any more).

For some reason setuptools isn't finding it:

jupiter:~ # easy_install gmpy
Searching for gmpy
Reading http://cheeseshop.python.org/pypi/gmpy/
Reading http://code.google.com/p/gmpy/
Reading http://cheeseshop.python.org/pypi/gmpy/1.02
No local packages or download links found for gmpy
error: Could not find suitable distribution for Requirement.parse('gmpy')


I believe that setuptools isn't ready to find packages on code.google.com
yet... ;-)

-- 
Jorge Godoy  [EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Alex Martelli
Jorge Godoy [EMAIL PROTECTED] wrote:

 [EMAIL PROTECTED] (Alex Martelli) writes:
 
  Incidentally (and I know you know that, Paul, but others interested in
  this thread might not) fast exact rational arithmetic (based on the LGPL
  library named GMP) is supplied, among other functionality, by module
  gmpy, currently found at http://code.google.com/p/gmpy/ (this version is
  more recent than the older one at sourceforce, which for some reason
  doesn't let me update things right any more).
 
 For some reason setuptools isn't finding it:
 
 jupiter:~ # easy_install gmpy
 Searching for gmpy
 Reading http://cheeseshop.python.org/pypi/gmpy/
 Reading http://code.google.com/p/gmpy/
 Reading http://cheeseshop.python.org/pypi/gmpy/1.02
 No local packages or download links found for gmpy
 error: Could not find suitable distribution for Requirement.parse('gmpy')
 
 
 I believe that setuptools isn't ready to find packages on code.google.com
 yet... ;-)

I'm not familiar with setuptools, what exactly is it looking for?

If it's looking for stuff to download it should start at

http://code.google.com/p/gmpy/downloads/list

(but what does it want -- the sources' zipfile, or some binary, and in
what format and with what naming convention?) -- I'll be glad to edit
the URL for gmpy at cheeseshop if some setuptools expert can explain
these subtleties... thanks for pointing out that there's a problem
btw!-)


Alex
-- 
http://mail.python.org/mailman/listinfo/python-list


setuptools and code.google.com (was Re: Signed zeros: is this a bug?)

2007-03-11 Thread Jorge Godoy
[EMAIL PROTECTED] (Alex Martelli) writes:

 I'm not familiar with setuptools, what exactly is it looking for?

 If it's looking for stuff to download it should start at

 http://code.google.com/p/gmpy/downloads/list

 (but what does it want -- the sources' zipfile, or some binary, and in
 what format and with what naming convention?) -- I'll be glad to edit
 the URL for gmpy at cheeseshop if some setuptools expert can explain
 these subtleties... thanks for pointing out that there's a problem
 btw!-)

Thanks for caring ;-)


It looks for several things: eggs (for the Python version it is being used),
zipfiles and tarballs (I dunno if it looks for more things). 

If it finds, for example, gmpy-1.0.2-py2.4.egg it won't install here 'cause I
use Python 2.5 and then it will continue searching for gmpy-1.0.2-py2.5.egg or
an alternative format that can be used.  The last resort is the tarball / zip
with the sources so that the package can be rebuilt. 

Probably other people that are more experienced with it can help more.  I'm
more an end user of it and I know the essential for my needs. 

I just pointed out because setuptools helps a lot on obtaining a package and
installing it (even if there's some building needed before installing). 


Sorry for not being able to help more.


With regards to the hyperlink, I believe that if the link on Pypi was to the
URL above it would be easier.  Another alternative is a link at the first
page.  And, of course, the last alternative is teaching setuptools how to work
with code.google.com -- if it doesn't already know -- as it learnt how to work
with SourceForge and its random mirrors.  I don't know how to write that
code, though.


Be seeing you,
-- 
Jorge Godoy  [EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Mark Dickinson
On Mar 11, 9:56 pm, [EMAIL PROTECTED] (Alex Martelli) wrote:
 That bug isn't formally closed yet, and the discussion's going on, we'll
 see.  Meanwhile can you try my patch 1678668 just to double check it
 does fix everything?  (It's agains the current HEAD of Python's svn).

It does, and all tests pass.  (Still on OS X 10.4.8/PowerPC;  I'll
test
it tomorrow on my Linux machine at work.)

Mark

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Signed zeros: is this a bug?

2007-03-11 Thread Paddy
On Mar 11, 10:49 pm, Paddy [EMAIL PROTECTED] wrote:
 On Mar 11, 9:28 pm, Paul Rubin http://[EMAIL PROTECTED] wrote:

  Dennis Lee Bieber [EMAIL PROTECTED] writes:

  Pardon? What is the right thing with signed zeros... In the last
   30 years I've been on machines that normalize floating zero into a true
   zero (all bits are zero: mantissa, exponent, and sign). This is the
   first time I've even seen a variable output as a negative 0.0!

  Most machines these days use IEEE 754 which supports negative zero.

 http://en.wikipedia.org/wiki/Negative_zero

 Isn't negative zero mathematically the same as zero? Isn't -0 just an
 artefact of the representation of floating point numbers? Shouldn't
 f(0) == f(-0) for all functions f?
 I read the wikipedia article about meteorologists using -0 to denote a
 negative number rounded to zero for the purposes of binning, i.e. if
 you want to tally days with temperature above and below zero, but it
 doesn't seem right. You should arrange for any temperature to be in
 only one range and record temperatures to their determined accuracy. a
 temperature of zero would only be in one bin and if a temperature is
 read as -0.2 and th rounding says it should be taken as zero then it
 should go in the same bin as any positive reading that is rounded to
 zero.
 Getting back to Python, shouldn't we strive to remove any distinction?
 a zero is a zero regardless of sign and a function like atan returning
 one of two different vaues for an argument of zero is actually
 mathematically not a bad thing to do?

 - Paddy.

A big thanks to Paul and Andre,
I think I have it now. The OP is investigating multivalued functions
where the function converges to different values when approached from
different directions. Floating point arithmetic being a best
compromise solution to the rational number system, distinguishes
between zero and minus zero as an important part of the compromise.
The OP wants to compute a function of zero and minus zero distinctly
and is hampered by Python not preserving the zero/minus zero
distinction in some cases - hence it being a bug.

Swell, Ta!

- Paddy.

Hey, I'm still learnin'. Sweet!

-- 
http://mail.python.org/mailman/listinfo/python-list