return (d & aw) ? 1 : -1;
}
+/* Return -1 if a<b, 1 if a>b, 0 if a=b or if b is NaN. */
+static inline int
+fixnum_float_cmp (EMACS_INT a, double b)
+{
+ double fa = (double)a;
+ if (fa == b)
+ {
+ /* This doesn't mean that a=b because the conversion may have
+ rounded, but b must be an integer that fits in an EMACS_INT
+ and we can compare in the integer domain instead. */
+ EMACS_INT ib = b; /* lossless conversion */
+ return a < ib ? -1 : a > ib;
+ }
+ else
+ return fa < b ? -1 : fa > b; /* return 0 if b is NaN */
+}
+
/* Return -1, 0 or 1 to indicate whether a<b, a=b or a>b in the sense of value<.
In particular 0 does not mean equality in the sense of Fequal, only
that the arguments cannot be ordered yet they can be compared (same
if (FIXNUMP (b))
return ia < XFIXNUM (b) ? -1 : 1; /* we know that a != b */
if (FLOATP (b))
- return ia < XFLOAT_DATA (b) ? -1 : ia > XFLOAT_DATA (b);
+ return fixnum_float_cmp (ia, XFLOAT_DATA (b));
if (BIGNUMP (b))
return -mpz_sgn (*xbignum_val (b));
}
if (FLOATP (b))
return fa < XFLOAT_DATA (b) ? -1 : fa > XFLOAT_DATA (b);
if (FIXNUMP (b))
- return fa < XFIXNUM (b) ? -1 : fa > XFIXNUM (b);
+ return -fixnum_float_cmp (XFIXNUM (b), fa);
if (BIGNUMP (b))
{
if (isnan (fa))
(1.5 . 1.6) (-1.3 . -1.2) (-13.0 . 12.0)
;; floats/fixnums
(1 . 1.1) (1.9 . 2) (-2.0 . 1) (-2 . 1.0)
+ ;; fixnums that can't be represented as floats
+ (72057594037927935 . 72057594037927936.0)
+ (72057594037927936.0 . 72057594037927937)
+ (-72057594037927936.0 . -72057594037927935)
+ (-72057594037927937 . -72057594037927936.0)
+ (2305843009213693951 . 2305843009213693952.0)
+
;; floats/bignums
(,big . ,(float (* 2 big))) (,(float big) . ,(* 2 big))
;; symbols
;; numbers
(0 . 0.0) (0 . -0.0) (0.0 . -0.0)
+ (72057594037927936 . 72057594037927936.0)
+ (1 . 0.0e+NaN)
+
;; symbols
(a . #:a)