preserve exactness in sqrt of ratios where possible

This commit is contained in:
Alex Shinn 2020-11-19 13:13:37 +09:00
parent 12636f4b19
commit 181b7fe7e4

18
eval.c
View file

@ -1662,8 +1662,10 @@ sexp sexp_exact_sqrt (sexp ctx, sexp self, sexp_sint_t n, sexp z) {
#endif
sexp sexp_sqrt (sexp ctx, sexp self, sexp_sint_t n, sexp z) {
#if SEXP_USE_BIGNUMS
#if SEXP_USE_BIGNUMS || SEXP_USE_RATIOS
sexp_gc_var2(res, rem);
#endif
#if SEXP_USE_BIGNUMS
if (sexp_bignump(z)) {
sexp_gc_preserve2(ctx, res, rem);
res = sexp_bignum_sqrt(ctx, z, &rem);
@ -1673,6 +1675,20 @@ sexp sexp_sqrt (sexp ctx, sexp self, sexp_sint_t n, sexp z) {
sexp_gc_release2(ctx);
return res;
}
#endif
#if SEXP_USE_RATIOS
if (sexp_ratiop(z)) {
sexp_gc_preserve2(ctx, res, rem);
res = sexp_sqrt(ctx, self, n, sexp_ratio_numerator(z));
rem = sexp_sqrt(ctx, self, n, sexp_ratio_denominator(z));
if (sexp_exactp(res) && sexp_exactp(rem)) {
res = sexp_make_ratio(ctx, res, rem);
} else {
res = sexp_inexact_sqrt(ctx, self, n, z);
}
sexp_gc_release2(ctx);
return res;
}
#endif
return sexp_inexact_sqrt(ctx, self, n, z);
}