]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix bignum comparisons with NaN
authorTom Tromey <tom@tromey.com>
Sat, 4 Aug 2018 16:50:35 +0000 (10:50 -0600)
committerTom Tromey <tom@tromey.com>
Sat, 4 Aug 2018 16:50:35 +0000 (10:50 -0600)
* src/data.c (isnan): Move earlier.
(bignumcompare): Explicitly handle NaN.
* test/src/data-tests.el (data-tests-min): Add NaN tests
for bignum.
(data-check-sign): Fix for previous patch.
* test/src/fns-tests.el (test-bignum-eql): Add NaN test.

src/data.c
test/src/data-tests.el
test/src/fns-tests.el

index 3d55d9d17d5bd848052283d884e4131d5321a1cd..4388a2b0ffc722b69259926cc71a58b8b822e052 100644 (file)
@@ -2397,6 +2397,10 @@ bool-vector.  IDX starts at 0.  */)
 \f
 /* Arithmetic functions */
 
+#ifndef isnan
+# define isnan(x) ((x) != (x))
+#endif
+
 static Lisp_Object
 bignumcompare (Lisp_Object num1, Lisp_Object num2,
               enum Arith_Comparison comparison)
@@ -2407,7 +2411,13 @@ bignumcompare (Lisp_Object num1, Lisp_Object num2,
   if (BIGNUMP (num1))
     {
       if (FLOATP (num2))
-       cmp = mpz_cmp_d (XBIGNUM (num1)->value, XFLOAT_DATA (num2));
+       {
+         /* Note that GMP doesn't define comparisons against NaN, so
+            we need to handle them specially.  */
+         if (isnan (XFLOAT_DATA (num2)))
+           return Qnil;
+         cmp = mpz_cmp_d (XBIGNUM (num1)->value, XFLOAT_DATA (num2));
+       }
       else if (FIXNUMP (num2))
         {
           if (sizeof (EMACS_INT) > sizeof (long) && XINT (num2) > LONG_MAX)
@@ -2431,7 +2441,13 @@ bignumcompare (Lisp_Object num1, Lisp_Object num2,
     {
       eassume (BIGNUMP (num2));
       if (FLOATP (num1))
-       cmp = - mpz_cmp_d (XBIGNUM (num2)->value, XFLOAT_DATA (num1));
+       {
+         /* Note that GMP doesn't define comparisons against NaN, so
+            we need to handle them specially.  */
+         if (isnan (XFLOAT_DATA (num1)))
+           return Qnil;
+         cmp = - mpz_cmp_d (XBIGNUM (num2)->value, XFLOAT_DATA (num1));
+       }
       else
         {
          eassume (FIXNUMP (num1));
@@ -3021,10 +3037,6 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
   return unbind_to (count, make_number (accum));
 }
 
-#ifndef isnan
-# define isnan(x) ((x) != (x))
-#endif
-
 static Lisp_Object
 float_arith_driver (double accum, ptrdiff_t argnum, enum arithop code,
                    ptrdiff_t nargs, Lisp_Object *args)
index 07159df48cf91c89735786adb3a54bd2c4117e80..ee6a3eb9222dffc40741466e067611c0d194b0b3 100644 (file)
   (should (isnan (min 0.0e+NaN)))
   (should (isnan (min 0.0e+NaN 1 2)))
   (should (isnan (min 1.0 0.0e+NaN)))
-  (should (isnan (min 1.0 0.0e+NaN 1.1))))
+  (should (isnan (min 1.0 0.0e+NaN 1.1)))
+  (should (isnan (min 1.0 0.0e+NaN 1.1 (1+ most-positive-fixnum))))
+  (should (isnan (max 1.0 0.0e+NaN 1.1 (1+ most-positive-fixnum)))))
 
 (defun data-tests-popcnt (byte)
   "Calculate the Hamming weight of BYTE."
@@ -618,6 +620,6 @@ comparing the subr with a much slower lisp implementation."
   (should (= (ash most-negative-fixnum 1)
              (* most-negative-fixnum 2)))
   (should (= (lsh most-negative-fixnum 1)
-             (* (abs most-negative-fixnum) 2))))
+             (* most-negative-fixnum 2))))
 
 ;;; data-tests.el ends here
index f5f3b89244122171fdf8c8c77cc0a481c117c9b7..d440cfabda4986ceb351c36211418a8ddd8a3fc7 100644 (file)
         (y (+ most-positive-fixnum 1)))
     (should (eq x x))
     (should (eql x y))
-    (should (equal x y))))
+    (should (equal x y))
+    (should-not (eql x 0.0e+NaN))))
 
 (provide 'fns-tests)