mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-07-04 03:36:36 +02:00
Properly handling +nan.0 and infinite comparisons.
This commit is contained in:
parent
f792329eed
commit
122d8b8a00
2 changed files with 42 additions and 9 deletions
21
bignum.c
21
bignum.c
|
@ -1528,7 +1528,16 @@ sexp sexp_compare (sexp ctx, sexp a, sexp b) {
|
|||
r = sexp_make_fixnum(f < g ? -1 : f == g ? 0 : 1);
|
||||
break;
|
||||
case SEXP_NUM_FLO_BIG:
|
||||
a = tmp = sexp_double_to_bignum(ctx, sexp_flonum_value(a));
|
||||
f = sexp_flonum_value(a);
|
||||
if (isinf(f)) {
|
||||
r = f > 0 ? SEXP_ONE : SEXP_NEG_ONE;
|
||||
break;
|
||||
} else if (isnan(f)) {
|
||||
r = sexp_xtype_exception(ctx, NULL, "can't compare NaN", a);
|
||||
break;
|
||||
} else {
|
||||
a = tmp = sexp_double_to_bignum(ctx, f);
|
||||
}
|
||||
/* ... FALLTHROUGH ... */
|
||||
case SEXP_NUM_BIG_BIG:
|
||||
r = sexp_make_fixnum(sexp_bignum_compare(a, b));
|
||||
|
@ -1536,8 +1545,14 @@ sexp sexp_compare (sexp ctx, sexp a, sexp b) {
|
|||
#if SEXP_USE_RATIOS
|
||||
case SEXP_NUM_FLO_RAT:
|
||||
f = sexp_flonum_value(a);
|
||||
g = sexp_ratio_to_double(b);
|
||||
r = sexp_make_fixnum(f < g ? -1 : f == g ? 0 : 1);
|
||||
if (isinf(f)) {
|
||||
r = f > 0 ? SEXP_ONE : SEXP_NEG_ONE;
|
||||
} else if (isnan(f)) {
|
||||
r = sexp_xtype_exception(ctx, NULL, "can't compare NaN", a);
|
||||
} else {
|
||||
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:
|
||||
|
|
30
vm.c
30
vm.c
|
@ -1750,8 +1750,14 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) {
|
|||
_ARG1 = sexp_make_boolean(i);
|
||||
} else {
|
||||
_ARG1 = sexp_compare(ctx, tmp1, tmp2);
|
||||
sexp_check_exception();
|
||||
_ARG1 = sexp_make_boolean(sexp_unbox_fixnum(_ARG1) < 0);
|
||||
if (sexp_exceptionp(_ARG1)) {
|
||||
if (strcmp("can't compare NaN", sexp_string_data(sexp_exception_message(_ARG1))) == 0)
|
||||
_ARG1 = SEXP_FALSE;
|
||||
else
|
||||
goto call_error_handler;
|
||||
} else {
|
||||
_ARG1 = sexp_make_boolean(sexp_unbox_fixnum(_ARG1) < 0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if SEXP_USE_FLONUMS
|
||||
|
@ -1775,8 +1781,14 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) {
|
|||
_ARG1 = sexp_make_boolean(i);
|
||||
} else {
|
||||
_ARG1 = sexp_compare(ctx, tmp1, tmp2);
|
||||
sexp_check_exception();
|
||||
_ARG1 = sexp_make_boolean(sexp_unbox_fixnum(_ARG1) <= 0);
|
||||
if (sexp_exceptionp(_ARG1)) {
|
||||
if (strcmp("can't compare NaN", sexp_string_data(sexp_exception_message(_ARG1))) == 0)
|
||||
_ARG1 = SEXP_FALSE;
|
||||
else
|
||||
goto call_error_handler;
|
||||
} else {
|
||||
_ARG1 = sexp_make_boolean(sexp_unbox_fixnum(_ARG1) <= 0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if SEXP_USE_FLONUMS
|
||||
|
@ -1828,8 +1840,14 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) {
|
|||
#endif
|
||||
/* neither is complex */
|
||||
_ARG1 = sexp_compare(ctx, tmp1, tmp2);
|
||||
sexp_check_exception();
|
||||
_ARG1 = sexp_make_boolean(_ARG1 == SEXP_ZERO);
|
||||
if (sexp_exceptionp(_ARG1)) {
|
||||
if (strcmp("can't compare NaN", sexp_string_data(sexp_exception_message(_ARG1))) == 0)
|
||||
_ARG1 = SEXP_FALSE;
|
||||
else
|
||||
goto call_error_handler;
|
||||
} else {
|
||||
_ARG1 = sexp_make_boolean(_ARG1 == SEXP_ZERO);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if SEXP_USE_FLONUMS
|
||||
|
|
Loading…
Add table
Reference in a new issue