On Nov 14, 2007, at 1:35 PM, Andy Dougherty wrote:
I'm forwarding a message I got about the f == 0.0 warnings. -- Andy Dougherty [EMAIL PROTECTED] ---------- Forwarded message ---------- Date: Wed, 14 Nov 2007 10:38:10 -0500 From: Jeffrey Kegler <[EMAIL PROTECTED]> To: Andy Dougherty <[EMAIL PROTECTED]> Subject: Could you forward this into the perl6 internals list Resent-Date: Wed, 14 Nov 2007 10:38:35 -0500 Resent-From: <[EMAIL PROTECTED]> I've been following the floating point issue for some time, but am not on the perl6 internals list, and didn't want to join to make a single comment. Could I ask you to forward this into the list? Bottom line: the floating point equality warning is the expression of a philosophy of math issue, and you may not be following the philosophy. That's cool. But it's not viable IMHO to not adhere to the philosophy, but try to keep the warning. The philosophy of math issue is that if you are taking floats as approximations of reals, equality does not usually mean anything useful. It almost never means what the programmer is trying to express via equality. Floating point zero (0.00) means zero plus or minus an error, just as with any other floating point number. Zero is not special in any sense. Are all your "special case" floating zeroes safe from being mistaken for certain very small but non-zero numbers in all implementations?
The issue here is, the main places we test for equality of floats is in an opcode(where the compiler can handle the approximation), or treating cases of -0.0 and 0.0 causing different results with standard libraries. Many of the equality checks are in fact explicitly checking for equality with 0.0(and consequently -0.0) because different libraries seem to have different handling for the two, intentionally or not. Most of parrot is sort of akin to kernel mode programming, don't use floats and find another way if you need floats.
However, we are hackers, not philosophers of mathematics (actually I'm both, but I'm talking now as a hacker). Floats on computers are what we hackers use them for, and if we find it useful to special case the bit pattern corresponding to zero, we can do it. We should, however, turn off the warning.
We can't use a bit pattern for all systems because that would require knowing the underlying size of a float, it's bit layout, and being sure that c can convert to and from it exactly(I don't believe c can nicely handle an 80 bit float). The issue isn't so much 0.0 but -0.0, which would have a different bit pattern and you lack guarantees about it, there are none! I've never heard of a portable float, and as a result, we can't assume anything. For the IEEE, -0.0 == 0.0 even though their bit patterns are different. In complex.pmc, all tests pass on ppc(darwin), i386(freebsd, plus smoke results seem ok), and amd64(freebsd, plus linux smokes), but if you remove one of the equality checks, one or more tests might fail, somewhere. Writing code like "if (i == 0.0) i = 0.0;" looks like a no-op, but you're also testing for -0.0 to handle libm issues. I'm not 100% sure how compilers handle -0.0 in source on systems that don't support -0.0 floats.
I hesitated to come in, because I'm not aware of the context. You may, for example, be trying to mix code that carefully adheres to the floating-point-equals-Platonic-idea-of-real-numbers philosophy, with code written on a it-works-so-what's-the-beef philosophy, in which case I can see why the problem keeps coming up.
I think most of parrot's use of floats is "higher programs will want them, so we need to provide them." If it weren't for want, there wouldn't be a pdd15.
Primary suggestion: You might consider simply turning off the warning in preference to heroic efforts to shut it up for cases which are actually no safer than any others. Other suggestions: If code rewrites are feasible, an additional boolean is not (certainly in the context of C code) all that expensive these days, and is a philosophically "right" answer. A more hackerly solution is to identify a range which won't be the result of normal computation and test for that. (If the value can never be less than zero let (f < 0.00) be the special case. Sorry to interrupt your work, but I've followed your list and seen this come up several times and I hoped this might help, thanks for your work, jeffrey kegler