unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Kevin Ryde <user42@zip.com.au>
Subject: mpz_cmp_d and NaNs in = and <
Date: Tue, 06 May 2003 09:24:35 +1000	[thread overview]
Message-ID: <87isspt1sc.fsf@zip.com.au> (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

             reply	other threads:[~2003-05-05 23:24 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-05-05 23:24 Kevin Ryde [this message]
2003-05-09 23:16 ` mpz_cmp_d and NaNs in = and < 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87isspt1sc.fsf@zip.com.au \
    --to=user42@zip.com.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).