Re: Signed zeros: is this a bug?
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?
[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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
# 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?
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?
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?
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?
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?
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?
[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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
[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?
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?)
[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?
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?
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