[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Reverting eqv? behavior for signed zeros and nans to 1.6 semantics
From: |
Aubrey Jaffer |
Subject: |
Re: Reverting eqv? behavior for signed zeros and nans to 1.6 semantics |
Date: |
Sun, 16 Jul 2006 17:13:50 -0400 (EDT) |
| From: Marius Vollmer <address@hidden>
| Date: Sun, 16 Jul 2006 21:04:20 +0300
|
| after enormous procrastination, I am now convinced that the change
| in semantics of eqv? from 1.6 to 1.8 was wrong, and I think that we
| should revert the eqv? behavior for the next 1.8.1 release. It's a
| bug in the design and should be fixed.
|
| (Credit goes to Aubrey Jaffer for pointing out the bug in the first
| place, and Kevin for making me understand.)
|
| R5RS is pretty clear about the relation between '=' and 'eqv?' and
| we should follow that (even tho one could argue that R5RS has not
| been written with signed zeros and NaNs in mind and R6RS will
| likely be different in this area).
|
| Specifically, 'eqv?' would be changed to return '#t' when comparing
| negative and positive zero:
|
| (eqv? 0.0 -0.0) => #t
Okay!
| and should return #f for nans:
|
| (eqv? +nan.0 +nan.0) => #f
IEEE-754 apparently chose to overload the floating-point equality
operator to detect NaNs to avoid having to define new floating-point
predicates. Guile already has a nan predicate. 754's low-level hack
should not be exposed in Scheme.
In the description of EQ?, R5RS states:
`Eq?''s behavior on numbers and characters is
implementation-dependent, but it will always return either true or
false, and will return true only when `eqv?' would also return true.
So if (eqv? +nan.0 +nan.0) returns false, then (eq? +nan.0 +nan.0)
cannot return true and must return false.
_Rationale:_ It will usually be possible to implement `eq?' much
more efficiently than `eqv?', for example, as a simple pointer
comparison instead of as some more complicated operation.
If (eq? +nan.0 +nan.0) is required to return #f, then EQ? in Guile is
prevented from being a simple pointer comparison.
| If you need to test the sign of zero by turning it into the
| corresponding infinity
|
| (> (/ 0.0) 0) => #t
| (> (/ -0.0) 0) => #f
|
| To test for a NaN, use 'nan?'.
|
| Ok?