* mpz_cmp_d and NaNs in = and <
@ 2003-05-05 23:24 Kevin Ryde
2003-05-09 23:16 ` Kevin Ryde
0 siblings, 1 reply; 7+ messages in thread
From: Kevin Ryde @ 2003-05-05 23:24 UTC (permalink / raw)
[-- Attachment #1: Type: text/plain, Size: 502 bytes --]
A concrete proposal for NaNs in = and <. As mentioned previously,
mpz_cmp_d doesn't accept them.
* numbers.c (scm_num_eq_p, scm_less_p): Don't pass NaN to mpz_cmp_d.
* tests/numbers.test (=, <): Add tests involving NaNs.
Are the comments correct about SCM_COMPLEXP numbers never having a
zero imaginary part? I suspect this means the mpz_cmp_d's in the
complex/bignum cases are not reached. In fact perhaps any comparison
(= complex non-complex) would be #f without any testing.
[-- Attachment #2: numbers.c.nan.diff --]
[-- Type: text/plain, Size: 2501 bytes --]
--- numbers.c.~1.181.~ 2003-05-04 09:09:49.000000000 +1000
+++ numbers.c 2003-05-05 12:04:05.000000000 +1000
@@ -2520,12 +2520,15 @@
scm_remember_upto_here_2 (x, y);
return SCM_BOOL (0 == cmp);
} else if (SCM_REALP (y)) {
- int cmp = mpz_cmp_d (SCM_I_BIG_MPZ (x), SCM_REAL_VALUE (y));
+ int cmp;
+ if (xisnan (SCM_REAL_VALUE (y))) return SCM_BOOL_F;
+ cmp = mpz_cmp_d (SCM_I_BIG_MPZ (x), SCM_REAL_VALUE (y));
scm_remember_upto_here_1 (x);
return SCM_BOOL (0 == cmp);
} else if (SCM_COMPLEXP (y)) {
int cmp;
if (0.0 != SCM_COMPLEX_IMAG (y)) return SCM_BOOL_F;
+ if (xisnan (SCM_COMPLEX_REAL (y))) return SCM_BOOL_F;
cmp = mpz_cmp_d (SCM_I_BIG_MPZ (x), SCM_COMPLEX_REAL (y));
scm_remember_upto_here_1 (x);
return SCM_BOOL (0 == cmp);
@@ -2536,7 +2539,9 @@
if (SCM_INUMP (y)) {
return SCM_BOOL (SCM_REAL_VALUE (x) == (double) SCM_INUM (y));
} else if (SCM_BIGP (y)) {
- int cmp = mpz_cmp_d (SCM_I_BIG_MPZ (y), SCM_REAL_VALUE (x));
+ int cmp;
+ if (xisnan (SCM_REAL_VALUE (x))) return SCM_BOOL_F;
+ cmp = mpz_cmp_d (SCM_I_BIG_MPZ (y), SCM_REAL_VALUE (x));
scm_remember_upto_here_1 (y);
return SCM_BOOL (0 == cmp);
} else if (SCM_REALP (y)) {
@@ -2554,6 +2559,7 @@
} else if (SCM_BIGP (y)) {
int cmp;
if (0.0 != SCM_COMPLEX_IMAG (x)) return SCM_BOOL_F;
+ if (xisnan (SCM_COMPLEX_REAL (x))) return SCM_BOOL_F;
cmp = mpz_cmp_d (SCM_I_BIG_MPZ (y), SCM_COMPLEX_REAL (x));
scm_remember_upto_here_1 (y);
return SCM_BOOL (0 == cmp);
@@ -2603,7 +2609,9 @@
scm_remember_upto_here_2 (x, y);
return SCM_BOOL (cmp < 0);
} else if (SCM_REALP (y)) {
- int cmp = mpz_cmp_d (SCM_I_BIG_MPZ (x), SCM_REAL_VALUE (y));
+ int cmp;
+ if (xisnan (SCM_REAL_VALUE (y))) return SCM_BOOL_F;
+ cmp = mpz_cmp_d (SCM_I_BIG_MPZ (x), SCM_REAL_VALUE (y));
scm_remember_upto_here_1 (x);
return SCM_BOOL (cmp < 0);
} else {
@@ -2613,7 +2621,9 @@
if (SCM_INUMP (y)) {
return SCM_BOOL (SCM_REAL_VALUE (x) < (double) SCM_INUM (y));
} else if (SCM_BIGP (y)) {
- int cmp = mpz_cmp_d (SCM_I_BIG_MPZ (y), SCM_REAL_VALUE (x));
+ int cmp;
+ if (xisnan (SCM_REAL_VALUE (x))) return SCM_BOOL_F;
+ cmp = mpz_cmp_d (SCM_I_BIG_MPZ (y), SCM_REAL_VALUE (x));
scm_remember_upto_here_1 (y);
return SCM_BOOL (cmp > 0);
} else if (SCM_REALP (y)) {
[-- Attachment #3: numbers.test.nan.diff --]
[-- Type: text/plain, Size: 2597 bytes --]
Index: numbers.test
===================================================================
RCS file: /cvsroot/guile/guile/guile-core/test-suite/tests/numbers.test,v
retrieving revision 1.19
diff -u -u -r1.19 numbers.test
--- numbers.test 5 May 2003 23:04:02 -0000 1.19
+++ numbers.test 5 May 2003 23:22:53 -0000
@@ -1157,7 +1157,30 @@
(expect-fail (= (+ 1 fixnum-max) fixnum-max))
(expect-fail (= fixnum-min (- fixnum-min 1)))
(expect-fail (= (- fixnum-min 1) fixnum-min))
- (expect-fail (= (+ fixnum-max 1) (- fixnum-min 1))))
+ (expect-fail (= (+ fixnum-max 1) (- fixnum-min 1)))
+
+ (pass-if (not (= +nan.0 +nan.0)))
+ (pass-if (not (= 0 +nan.0)))
+ (pass-if (not (= +nan.0 0)))
+ (pass-if (not (= 1 +nan.0)))
+ (pass-if (not (= +nan.0 1)))
+ (pass-if (not (= -1 +nan.0)))
+ (pass-if (not (= +nan.0 -1)))
+
+ (pass-if (not (= (ash 1 256) +nan.0)))
+ (pass-if (not (= +nan.0 (ash 1 256))))
+ (pass-if (not (= (- (ash 1 256)) +nan.0)))
+ (pass-if (not (= +nan.0 (- (ash 1 256)))))
+
+ (pass-if (not (= (ash 1 8192) +nan.0)))
+ (pass-if (not (= +nan.0 (ash 1 8192))))
+ (pass-if (not (= (- (ash 1 8192)) +nan.0)))
+ (pass-if (not (= +nan.0 (- (ash 1 8192)))))
+
+ ;; in gmp prior to 4.2, mpz_cmp_d ended up treating NaN as 3*2^1023, make
+ ;; sure we've avoided that
+ (pass-if (not (= (ash 3 1023) +nan.0)))
+ (pass-if (not (= +nan.0 (ash 3 1023)))))
;;;
;;; <
@@ -1486,7 +1509,34 @@
(< (- fixnum-min 1) fixnum-min))
(pass-if "n = fixnum-min - 1"
- (not (< (- fixnum-min 1) (- fixnum-min 1))))))
+ (not (< (- fixnum-min 1) (- fixnum-min 1)))))
+
+ (pass-if (not (< +nan.0 +nan.0)))
+ (pass-if (not (< 0 +nan.0)))
+ (pass-if (not (< +nan.0 0)))
+ (pass-if (not (< 1 +nan.0)))
+ (pass-if (not (< +nan.0 1)))
+ (pass-if (not (< -1 +nan.0)))
+ (pass-if (not (< +nan.0 -1)))
+
+ (pass-if (not (< (ash 1 256) +nan.0)))
+ (pass-if (not (< +nan.0 (ash 1 256))))
+ (pass-if (not (< (- (ash 1 256)) +nan.0)))
+ (pass-if (not (< +nan.0 (- (ash 1 256)))))
+
+ (pass-if (not (< (ash 1 8192) +nan.0)))
+ (pass-if (not (< +nan.0 (ash 1 8192))))
+ (pass-if (not (< (- (ash 1 8192)) +nan.0)))
+ (pass-if (not (< +nan.0 (- (ash 1 8192)))))
+
+ ;; in gmp prior to 4.2, mpz_cmp_d ended up treating NaN as 3*2^1023, make
+ ;; sure we've avoided that
+ (pass-if (not (< (ash 3 1023) +nan.0)))
+ (pass-if (not (< (1+ (ash 3 1023)) +nan.0)))
+ (pass-if (not (< (1- (ash 3 1023)) +nan.0)))
+ (pass-if (not (< +nan.0 (ash 3 1023))))
+ (pass-if (not (< +nan.0 (1+ (ash 3 1023)))))
+ (pass-if (not (< +nan.0 (1- (ash 3 1023))))))
;;;
;;; >
[-- Attachment #4: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: mpz_cmp_d and NaNs in = and <
2003-05-05 23:24 mpz_cmp_d and NaNs in = and < Kevin Ryde
@ 2003-05-09 23:16 ` Kevin Ryde
2003-05-10 12:52 ` Marius Vollmer
0 siblings, 1 reply; 7+ messages in thread
From: Kevin Ryde @ 2003-05-09 23:16 UTC (permalink / raw)
I wrote:
>
> * numbers.c (scm_num_eq_p, scm_less_p): Don't pass NaN to mpz_cmp_d.
> * tests/numbers.test (=, <): Add tests involving NaNs.
I applied this change. I left in the tests on complex numbers in `=';
someone smarter than me will have to advise whether it's true in fact
that they're not reached (on account of the imaginary part always
being non-zero).
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: mpz_cmp_d and NaNs in = and <
2003-05-09 23:16 ` Kevin Ryde
@ 2003-05-10 12:52 ` Marius Vollmer
2003-05-12 23:13 ` Kevin Ryde
0 siblings, 1 reply; 7+ messages in thread
From: Marius Vollmer @ 2003-05-10 12:52 UTC (permalink / raw)
Cc: guile-devel
Kevin Ryde <user42@zip.com.au> writes:
> I applied this change. I left in the tests on complex numbers in `=';
> someone smarter than me will have to advise whether it's true in fact
> that they're not reached (on account of the imaginary part always
> being non-zero).
I think that a lot of places expect it to be true that all complex
number objects in Guile have a non-zero imaginary part. But your
conservative approach is OK, nevertheless, and should probably remain
that way. For example, we can't currently represent negative
imaginary zero. we might want to change that, maybe.
--
GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: mpz_cmp_d and NaNs in = and <
2003-05-10 12:52 ` Marius Vollmer
@ 2003-05-12 23:13 ` Kevin Ryde
2003-05-13 10:21 ` rm
0 siblings, 1 reply; 7+ messages in thread
From: Kevin Ryde @ 2003-05-12 23:13 UTC (permalink / raw)
Marius Vollmer <mvo@zagadka.de> writes:
>
> For example, we can't currently represent negative imaginary zero.
Ah yes, I guess the ==0 in scm_make_complex doesn't recognise the
distincation.
> we might want to change that, maybe.
Personally I'm not a fan of negative zero, it's pretty hard to see a
proper use for it.
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: mpz_cmp_d and NaNs in = and <
2003-05-12 23:13 ` Kevin Ryde
@ 2003-05-13 10:21 ` rm
2003-05-17 1:12 ` Kevin Ryde
0 siblings, 1 reply; 7+ messages in thread
From: rm @ 2003-05-13 10:21 UTC (permalink / raw)
Cc: guile-devel
On Tue, May 13, 2003 at 09:13:54AM +1000, Kevin Ryde wrote:
> Marius Vollmer <mvo@zagadka.de> writes:
> >
> > For example, we can't currently represent negative imaginary zero.
>
> Ah yes, I guess the ==0 in scm_make_complex doesn't recognise the
> distincation.
>
> > we might want to change that, maybe.
>
> Personally I'm not a fan of negative zero, it's pretty hard to see a
> proper use for it.
Divide by it and you'll see :-)
Ralfd
>
> _______________________________________________
> Guile-devel mailing list
> Guile-devel@gnu.org
> http://mail.gnu.org/mailman/listinfo/guile-devel
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: mpz_cmp_d and NaNs in = and <
2003-05-13 10:21 ` rm
@ 2003-05-17 1:12 ` Kevin Ryde
2003-05-17 11:19 ` Marius Vollmer
0 siblings, 1 reply; 7+ messages in thread
From: Kevin Ryde @ 2003-05-17 1:12 UTC (permalink / raw)
rm@fabula.de writes:
>
> Divide by it and you'll see :-)
Oh, well, all I mean is that it's hard to see what it could represent.
A sort of remnant parity indicating how many positives and negatives
went into a product or something. But I don't pretend to any great
expertise in this sort of area, so maybe it's good for something.
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: mpz_cmp_d and NaNs in = and <
2003-05-17 1:12 ` Kevin Ryde
@ 2003-05-17 11:19 ` Marius Vollmer
0 siblings, 0 replies; 7+ messages in thread
From: Marius Vollmer @ 2003-05-17 11:19 UTC (permalink / raw)
Kevin Ryde <user42@zip.com.au> writes:
> rm@fabula.de writes:
> >
> > Divide by it and you'll see :-)
>
> Oh, well, all I mean is that it's hard to see what it could represent.
> A sort of remnant parity indicating how many positives and negatives
> went into a product or something. But I don't pretend to any great
> expertise in this sort of area, so maybe it's good for something.
There ought to be some good stuff in
Branch Cuts for Complex Elementary Functions,
or Much Ado About Nothing's Sign Bit
in The State of the Art in Numerical Analysis,
(eds. Iserles and Powell), Clarendon Press, Oxford, 1987.
but I couldn't find an online copy.
--
GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2003-05-17 11:19 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-05-05 23:24 mpz_cmp_d and NaNs in = and < Kevin Ryde
2003-05-09 23:16 ` Kevin Ryde
2003-05-10 12:52 ` Marius Vollmer
2003-05-12 23:13 ` Kevin Ryde
2003-05-13 10:21 ` rm
2003-05-17 1:12 ` Kevin Ryde
2003-05-17 11:19 ` Marius Vollmer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).