mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-21 06:39:17 +02:00
/ returns ratios when possible
This commit is contained in:
parent
3ff658e3a7
commit
3b44424140
2 changed files with 25 additions and 2 deletions
23
opt/bignum.c
23
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) {
|
sexp sexp_div (sexp ctx, sexp a, sexp b) {
|
||||||
int at=sexp_number_type(a), bt=sexp_number_type(b);
|
int at=sexp_number_type(a), bt=sexp_number_type(b);
|
||||||
|
#if ! SEXP_USE_RATIOS
|
||||||
double f;
|
double f;
|
||||||
|
#endif
|
||||||
sexp r=SEXP_VOID;
|
sexp r=SEXP_VOID;
|
||||||
sexp_gc_var2(tmp, rem);
|
sexp_gc_var2(tmp, rem);
|
||||||
sexp_gc_preserve2(ctx, 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);
|
r = sexp_type_exception(ctx, NULL, SEXP_NUMBER, b);
|
||||||
break;
|
break;
|
||||||
case SEXP_NUM_FIX_FIX:
|
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);
|
f = sexp_fixnum_to_double(a) / sexp_fixnum_to_double(b);
|
||||||
r = ((f == trunc(f)) ? sexp_make_fixnum((sexp_sint_t)f)
|
r = ((f == trunc(f)) ? sexp_make_fixnum((sexp_sint_t)f)
|
||||||
: sexp_make_flonum(ctx, f));
|
: sexp_make_flonum(ctx, f));
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case SEXP_NUM_FIX_FLO:
|
case SEXP_NUM_FIX_FLO:
|
||||||
r = sexp_make_flonum(ctx, sexp_fixnum_to_double(a)/sexp_flonum_value(b));
|
r = sexp_make_flonum(ctx, sexp_fixnum_to_double(a)/sexp_flonum_value(b));
|
||||||
break;
|
break;
|
||||||
case SEXP_NUM_FIX_BIG:
|
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;
|
break;
|
||||||
case SEXP_NUM_FLO_FIX:
|
case SEXP_NUM_FLO_FIX:
|
||||||
r = sexp_make_flonum(ctx, sexp_flonum_value(a)/sexp_fixnum_to_double(b));
|
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));
|
r = sexp_make_flonum(ctx, sexp_flonum_value(a) / sexp_bignum_to_double(b));
|
||||||
break;
|
break;
|
||||||
case SEXP_NUM_BIG_FIX:
|
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);
|
b = tmp = sexp_fixnum_to_bignum(ctx, b);
|
||||||
/* ... FALLTHROUGH ... */
|
#endif
|
||||||
|
/* ... FALLTHROUGH if ! SEXP_USE_RATIOS ... */
|
||||||
case SEXP_NUM_BIG_BIG:
|
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);
|
r = sexp_bignum_quot_rem(ctx, &rem, a, b);
|
||||||
if (sexp_bignum_normalize(rem) != SEXP_ZERO)
|
if (sexp_bignum_normalize(rem) != SEXP_ZERO)
|
||||||
r = sexp_make_flonum(ctx, sexp_bignum_to_double(a)
|
r = sexp_make_flonum(ctx, sexp_bignum_to_double(a)
|
||||||
/ sexp_bignum_to_double(b));
|
/ sexp_bignum_to_double(b));
|
||||||
else
|
else
|
||||||
r = sexp_bignum_normalize(r);
|
r = sexp_bignum_normalize(r);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case SEXP_NUM_BIG_FLO:
|
case SEXP_NUM_BIG_FLO:
|
||||||
r = sexp_make_flonum(ctx, sexp_bignum_to_double(a) / sexp_flonum_value(b));
|
r = sexp_make_flonum(ctx, sexp_bignum_to_double(a) / sexp_flonum_value(b));
|
||||||
|
|
4
vm.c
4
vm.c
|
@ -1473,6 +1473,9 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) {
|
||||||
#endif
|
#endif
|
||||||
sexp_raise("divide by zero", SEXP_NULL);
|
sexp_raise("divide by zero", SEXP_NULL);
|
||||||
} else if (sexp_fixnump(tmp1) && sexp_fixnump(tmp2)) {
|
} else if (sexp_fixnump(tmp1) && sexp_fixnump(tmp2)) {
|
||||||
|
#if SEXP_USE_RATIOS
|
||||||
|
_ARG1 = sexp_make_ratio(ctx, tmp1, tmp2);
|
||||||
|
#else
|
||||||
#if SEXP_USE_FLONUMS
|
#if SEXP_USE_FLONUMS
|
||||||
tmp1 = sexp_fixnum_to_flonum(ctx, tmp1);
|
tmp1 = sexp_fixnum_to_flonum(ctx, tmp1);
|
||||||
tmp2 = sexp_fixnum_to_flonum(ctx, tmp2);
|
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));
|
_ARG1 = sexp_make_fixnum(sexp_flonum_value(_ARG1));
|
||||||
#else
|
#else
|
||||||
_ARG1 = sexp_fx_div(tmp1, tmp2);
|
_ARG1 = sexp_fx_div(tmp1, tmp2);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if SEXP_USE_BIGNUMS
|
#if SEXP_USE_BIGNUMS
|
||||||
|
|
Loading…
Add table
Reference in a new issue