Andy Wingo <wi...@pobox.com> writes: >> (scm_difference): (- 0 0.0) now returns -0.0. Previously it returned >> 0.0. Also make sure that (- 0 0.0+0.0i) will return -0.0-0.0i. > > Is this right? I can convince myself both ways.
I'm not 100% confident, but I'm pretty sure it's the right thing. As far as I can tell, the semantics of the signed zeroes are based on one-sided limits, so (f 0.0) aka (f +0.0) should be the limit of (f x) as x approaches zero from the right, similarly for (f -0.0) except approaching from the left. (f +inf.0) and (f -inf.0) should also be defined in terms of limits. I don't know how this is handled when more than one of these special values is present in the operand list. As for the rules of when to return 0.0 vs -0.0, I'm not sure. IEEE 754 certainly produces -0.0 when a negative number underflows, but -0.0 is returned in more cases than that. For example, there is no underflow for (+ -0.0 -0.0) or (- 0.0). Based on the rules I know about, the pattern seems to be that if the operation is defined in terms of a limit (i.e. if +0.0, -0.0, +inf.0, or -inf.0 appears as an operand), and the result of the operation is known to approach zero from the left, then -0.0 is returned, otherwise 0.0 is returned. In this case, (- 0 0.0) can be defined as the limit of (- 0 x) as x approaches zero from the right, in which case the result approaches zero from the left. Another argument is that some Schemes apparently take the position that an inexact zero is "weaker" than an exact 0, for example by evaluating (/ 0 0.0) => 0, as pointed out by Aubrey Jaffer in the "Division by zero" section of: http://people.csail.mit.edu/jaffer/III/RAWI In any case, the R6RS explicitly gives these examples, which are widely accepted rules for the signed zeroes: (- 0.0) ==> -0.0 (- 0.0 0.0) ==> 0.0 Therefore, if we decide that (- 0 0.0) should be 0.0 instead of -0.0, then you'll have to change the compiler to no longer change (- x) to (- x 0). Best, Mark