mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-17 10:27:41 +00:00
Fix bignum comparisons with NaN
* 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.
This commit is contained in:
parent
bc8ff54efe
commit
91d505d8e2
3 changed files with 24 additions and 9 deletions
24
src/data.c
24
src/data.c
|
|
@ -2397,6 +2397,10 @@ bool-vector. IDX starts at 0. */)
|
|||
|
||||
/* 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)
|
||||
|
|
|
|||
|
|
@ -105,7 +105,9 @@
|
|||
(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
|
||||
|
|
|
|||
|
|
@ -599,6 +599,7 @@
|
|||
(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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue