From 181b7fe7e4d6b6685c99cb3811e0014b3f316ee6 Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Thu, 19 Nov 2020 13:13:37 +0900 Subject: [PATCH] preserve exactness in sqrt of ratios where possible --- eval.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/eval.c b/eval.c index fc6e4818..1d44ea22 100644 --- a/eval.c +++ b/eval.c @@ -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); }