diff options
author | Marius Vollmer <mvo@zagadka.de> | 2002-05-08 20:11:27 +0000 |
---|---|---|
committer | Marius Vollmer <mvo@zagadka.de> | 2002-05-08 20:11:27 +0000 |
commit | 96d00047de0458bbfdecfbdb3520e9ea0a9e8fe5 (patch) | |
tree | a5dbbf67e082f5e83f39d93a3887469324fbe7fd /libguile/eq.c | |
parent | fc194577017925ac30bad3dadf5d442aeaaee8a3 (diff) | |
download | guile-96d00047de0458bbfdecfbdb3520e9ea0a9e8fe5.tar.gz |
(real_eqv): New.
(scm_eqv_p): Use it when comparing reals and complexes.
Diffstat (limited to 'libguile/eq.c')
-rw-r--r-- | libguile/eq.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/libguile/eq.c b/libguile/eq.c index b159f2433..5dc73b6ed 100644 --- a/libguile/eq.c +++ b/libguile/eq.c @@ -66,6 +66,15 @@ SCM_DEFINE1 (scm_eq_p, "eq?", scm_tc7_rpsubr, } #undef FUNC_NAME +/* We compare doubles in a special way for 'eqv?' to be able to + distinguish plus and minus zero and to identify NaNs. +*/ + +static int +real_eqv (double x, double y) +{ + return !memcmp (&x, &y, sizeof(double)); +} SCM_DEFINE1 (scm_eqv_p, "eqv?", scm_tc7_rpsubr, (SCM x, SCM y), @@ -90,11 +99,13 @@ SCM_DEFINE1 (scm_eqv_p, "eqv?", scm_tc7_rpsubr, { if (SCM_SLOPPY_REALP (x)) return SCM_BOOL (SCM_SLOPPY_COMPLEXP (y) - && SCM_REAL_VALUE (x) == SCM_COMPLEX_REAL (y) + && real_eqv (SCM_REAL_VALUE (x), + SCM_COMPLEX_REAL (y)) && 0.0 == SCM_COMPLEX_IMAG (y)); else return SCM_BOOL (SCM_SLOPPY_REALP (y) - && SCM_COMPLEX_REAL (x) == SCM_REAL_VALUE (y) + && real_eqv (SCM_COMPLEX_REAL (x), + SCM_REAL_VALUE (y)) && SCM_COMPLEX_IMAG (x) == 0.0); } return SCM_BOOL_F; @@ -104,10 +115,12 @@ SCM_DEFINE1 (scm_eqv_p, "eqv?", scm_tc7_rpsubr, if (SCM_BIGP (x)) { return SCM_BOOL (0 == scm_bigcomp (x, y)); } else if (SCM_SLOPPY_REALP (x)) { - return SCM_BOOL (SCM_REAL_VALUE (x) == SCM_REAL_VALUE (y)); + return SCM_BOOL (real_eqv (SCM_REAL_VALUE (x), SCM_REAL_VALUE (y))); } else { /* complex */ - return SCM_BOOL (SCM_COMPLEX_REAL (x) == SCM_COMPLEX_REAL (y) - && SCM_COMPLEX_IMAG (x) == SCM_COMPLEX_IMAG (y)); + return SCM_BOOL (real_eqv (SCM_COMPLEX_REAL (x), + SCM_COMPLEX_REAL (y)) + && real_eqv (SCM_COMPLEX_IMAG (x), + SCM_COMPLEX_IMAG (y))); } } return SCM_BOOL_F; |