diff --git a/include/chibi/sexp.h b/include/chibi/sexp.h index 1a81cdc4..f3d9f6b5 100755 --- a/include/chibi/sexp.h +++ b/include/chibi/sexp.h @@ -802,6 +802,9 @@ SEXP_API sexp sexp_make_unsigned_integer(sexp ctx, sexp_luint_t x); #define sexp_shift_epoch(x) ((x)-SEXP_EPOCH_OFFSET) #define sexp_unshift_epoch(x) ((x)+SEXP_EPOCH_OFFSET) +#define sexp_infp(x) (sexp_flonump(x) && isinf(sexp_flonum_value(x))) +#define sexp_nanp(x) (sexp_flonump(x) && isnan(sexp_flonum_value(x))) + /*************************** field accessors **************************/ #if SEXP_USE_SAFE_ACCESSORS diff --git a/opt/bignum.c b/opt/bignum.c index aa73e6a8..def182e5 100644 --- a/opt/bignum.c +++ b/opt/bignum.c @@ -1479,7 +1479,7 @@ sexp sexp_remainder (sexp ctx, sexp a, sexp b) { sexp sexp_compare (sexp ctx, sexp a, sexp b) { int at=sexp_number_type(a), bt=sexp_number_type(b); sexp r=SEXP_VOID; - double f; + double f, g; sexp_gc_var1(tmp); sexp_gc_preserve1(ctx, tmp); if (at > bt) { @@ -1502,27 +1502,31 @@ sexp sexp_compare (sexp ctx, sexp a, sexp b) { r = sexp_make_fixnum(sexp_unbox_fixnum(a) - sexp_unbox_fixnum(b)); break; case SEXP_NUM_FIX_FLO: - f = sexp_fixnum_to_double(a) - sexp_flonum_value(b); - r = sexp_make_fixnum(f > 0.0 ? 1 : f == 0.0 ? 0 : -1); + f = sexp_fixnum_to_double(a); + g = sexp_flonum_value(b); + r = sexp_make_fixnum(f < g ? -1 : f == g ? 0 : 1); break; case SEXP_NUM_FIX_BIG: r = sexp_make_fixnum(sexp_bignum_sign(b) < 0 ? 1 : -1); break; case SEXP_NUM_FLO_FLO: - f = sexp_flonum_value(a) - sexp_flonum_value(b); - r = sexp_make_fixnum(f > 0.0 ? 1 : f == 0.0 ? 0 : -1); + f = sexp_flonum_value(a); + g = sexp_flonum_value(b); + r = sexp_make_fixnum(f < g ? -1 : f == g ? 0 : 1); break; case SEXP_NUM_FLO_BIG: - f = sexp_flonum_value(a) - sexp_bignum_to_double(b); - r = sexp_make_fixnum(f > 0.0 ? 1 : f == 0.0 ? 0 : -1); + f = sexp_flonum_value(a); + g = sexp_bignum_to_double(b); + r = sexp_make_fixnum(f < g ? -1 : f == g ? 0 : 1); break; case SEXP_NUM_BIG_BIG: r = sexp_make_fixnum(sexp_bignum_compare(a, b)); break; #if SEXP_USE_RATIOS case SEXP_NUM_FLO_RAT: - f = sexp_flonum_value(a) - sexp_ratio_to_double(b); - r = sexp_make_fixnum(f > 0.0 ? 1 : f == 0.0 ? 0 : -1); + f = sexp_flonum_value(a); + g = sexp_ratio_to_double(b); + r = sexp_make_fixnum(f < g ? -1 : f == g ? 0 : 1); break; case SEXP_NUM_FIX_RAT: case SEXP_NUM_BIG_RAT: diff --git a/tests/numeric-tests.scm b/tests/numeric-tests.scm index 5f720e78..dc087edd 100644 --- a/tests/numeric-tests.scm +++ b/tests/numeric-tests.scm @@ -119,6 +119,30 @@ (-18446744078004518913 -18446744069414584321 79228162514264337597838917632 4294967296 -1)) (sign-combinations (+ 1 (expt 2 64)) (expt 2 32))) +(test #f (< +nan.0 +nan.0)) +(test #f (<= +nan.0 +nan.0)) +(test #f (= +nan.0 +nan.0)) +(test #f (>= +nan.0 +nan.0)) +(test #f (> +nan.0 +nan.0)) + +(test #f (< +inf.0 +inf.0)) +(test #t (<= +inf.0 +inf.0)) +(test #t (= +inf.0 +inf.0)) +(test #t (>= +inf.0 +inf.0)) +(test #f (> +inf.0 +inf.0)) + +(test #f (< -inf.0 -inf.0)) +(test #t (<= -inf.0 -inf.0)) +(test #t (= -inf.0 -inf.0)) +(test #t (>= -inf.0 -inf.0)) +(test #f (> -inf.0 -inf.0)) + +(test #t (< -inf.0 +inf.0)) +(test #t (<= -inf.0 +inf.0)) +(test #f (= -inf.0 +inf.0)) +(test #f (>= -inf.0 +inf.0)) +(test #f (> -inf.0 +inf.0)) + (cond-expand (ratios (test #t (< 1/2 1.0))