diff --git a/opt/bignum.c b/opt/bignum.c index 4d6522e2..12314593 100644 --- a/opt/bignum.c +++ b/opt/bignum.c @@ -1086,7 +1086,9 @@ sexp sexp_mul (sexp ctx, sexp a, sexp b) { sexp sexp_div (sexp ctx, sexp a, sexp b) { int at=sexp_number_type(a), bt=sexp_number_type(b); +#if ! SEXP_USE_RATIOS double f; +#endif sexp r=SEXP_VOID; sexp_gc_var2(tmp, rem); sexp_gc_preserve2(ctx, tmp, rem); @@ -1105,15 +1107,23 @@ sexp sexp_div (sexp ctx, sexp a, sexp b) { r = sexp_type_exception(ctx, NULL, SEXP_NUMBER, b); break; case SEXP_NUM_FIX_FIX: +#if SEXP_USE_RATIOS + r = sexp_make_ratio(ctx, a, b); +#else f = sexp_fixnum_to_double(a) / sexp_fixnum_to_double(b); r = ((f == trunc(f)) ? sexp_make_fixnum((sexp_sint_t)f) : sexp_make_flonum(ctx, f)); +#endif break; case SEXP_NUM_FIX_FLO: r = sexp_make_flonum(ctx, sexp_fixnum_to_double(a)/sexp_flonum_value(b)); break; case SEXP_NUM_FIX_BIG: - r = sexp_make_flonum(ctx, sexp_fixnum_to_double(a)/sexp_bignum_to_double(b)); +#if SEXP_USE_RATIOS + r = sexp_make_ratio(ctx, a, b); +#else + r = sexp_make_flonum(ctx, sexp_fixnum_to_double(a)/sexp_bignum_to_double(b)); +#endif break; case SEXP_NUM_FLO_FIX: r = sexp_make_flonum(ctx, sexp_flonum_value(a)/sexp_fixnum_to_double(b)); @@ -1125,15 +1135,24 @@ sexp sexp_div (sexp ctx, sexp a, sexp b) { r = sexp_make_flonum(ctx, sexp_flonum_value(a) / sexp_bignum_to_double(b)); break; case SEXP_NUM_BIG_FIX: +#if SEXP_USE_RATIOS + r = sexp_make_ratio(ctx, a, b); + break; +#else b = tmp = sexp_fixnum_to_bignum(ctx, b); - /* ... FALLTHROUGH ... */ +#endif + /* ... FALLTHROUGH if ! SEXP_USE_RATIOS ... */ case SEXP_NUM_BIG_BIG: +#if SEXP_USE_RATIOS + r = sexp_make_ratio(ctx, a, b); +#else r = sexp_bignum_quot_rem(ctx, &rem, a, b); if (sexp_bignum_normalize(rem) != SEXP_ZERO) r = sexp_make_flonum(ctx, sexp_bignum_to_double(a) / sexp_bignum_to_double(b)); else r = sexp_bignum_normalize(r); +#endif break; case SEXP_NUM_BIG_FLO: r = sexp_make_flonum(ctx, sexp_bignum_to_double(a) / sexp_flonum_value(b)); diff --git a/vm.c b/vm.c index 79f40145..01727bee 100644 --- a/vm.c +++ b/vm.c @@ -1473,6 +1473,9 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) { #endif sexp_raise("divide by zero", SEXP_NULL); } else if (sexp_fixnump(tmp1) && sexp_fixnump(tmp2)) { +#if SEXP_USE_RATIOS + _ARG1 = sexp_make_ratio(ctx, tmp1, tmp2); +#else #if SEXP_USE_FLONUMS tmp1 = sexp_fixnum_to_flonum(ctx, tmp1); tmp2 = sexp_fixnum_to_flonum(ctx, tmp2); @@ -1481,6 +1484,7 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) { _ARG1 = sexp_make_fixnum(sexp_flonum_value(_ARG1)); #else _ARG1 = sexp_fx_div(tmp1, tmp2); +#endif #endif } #if SEXP_USE_BIGNUMS