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) {
|
||||
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));
|
||||
|
|
4
vm.c
4
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
|
||||
|
|
Loading…
Add table
Reference in a new issue