summaryrefslogtreecommitdiff
path: root/libguile/numbers.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2022-01-06 22:07:20 +0100
committerAndy Wingo <wingo@pobox.com>2022-01-13 09:37:17 +0100
commit63a18a6c1a2eae570c5de2b9eb866b20bc5e5e5e (patch)
treea6dbda388456eb168061d28607e7e1754564735d /libguile/numbers.c
parent9a91c20a551484f6a71bb35fa47b10f75f502c74 (diff)
downloadguile-63a18a6c1a2eae570c5de2b9eb866b20bc5e5e5e.tar.gz
Reimplement exact-integer-sqrt with integers.[ch]
* libguile/numbers.c (scm_exact_integer_sqrt): Call out. * libguile/integers.h: * libguile/integers.c (scm_integer_exact_sqrt_i): (scm_integer_exact_sqrt_z): New internal functions.
Diffstat (limited to 'libguile/numbers.c')
-rw-r--r--libguile/numbers.c41
1 files changed, 10 insertions, 31 deletions
diff --git a/libguile/numbers.c b/libguile/numbers.c
index 330ea2cdd..7567ced89 100644
--- a/libguile/numbers.c
+++ b/libguile/numbers.c
@@ -7374,41 +7374,20 @@ SCM_DEFINE (scm_i_exact_integer_sqrt, "exact-integer-sqrt", 1, 0, 0,
void
scm_exact_integer_sqrt (SCM k, SCM *sp, SCM *rp)
{
- if (SCM_LIKELY (SCM_I_INUMP (k)))
+ if (SCM_I_INUMP (k))
{
- if (SCM_I_INUM (k) > 0)
- {
- mp_limb_t kk, ss, rr;
-
- kk = SCM_I_INUM (k);
- if (mpn_sqrtrem (&ss, &rr, &kk, 1) == 0)
- rr = 0;
- *sp = SCM_I_MAKINUM (ss);
- *rp = SCM_I_MAKINUM (rr);
- }
- else if (SCM_I_INUM (k) == 0)
- *sp = *rp = SCM_INUM0;
- else
- scm_wrong_type_arg_msg ("exact-integer-sqrt", SCM_ARG1, k,
- "exact non-negative integer");
+ scm_t_inum kk = SCM_I_INUM (k);
+ if (kk >= 0)
+ return scm_integer_exact_sqrt_i (kk, sp, rp);
}
- else if (SCM_LIKELY (SCM_BIGP (k)))
+ else if (SCM_BIGP (k))
{
- SCM s, r;
-
- if (mpz_sgn (SCM_I_BIG_MPZ (k)) < 0)
- scm_wrong_type_arg_msg ("exact-integer-sqrt", SCM_ARG1, k,
- "exact non-negative integer");
- s = scm_i_mkbig ();
- r = scm_i_mkbig ();
- mpz_sqrtrem (SCM_I_BIG_MPZ (s), SCM_I_BIG_MPZ (r), SCM_I_BIG_MPZ (k));
- scm_remember_upto_here_1 (k);
- *sp = scm_i_normbig (s);
- *rp = scm_i_normbig (r);
+ struct scm_bignum *zk = scm_bignum (k);
+ if (!scm_is_integer_negative_z (zk))
+ return scm_integer_exact_sqrt_z (zk, sp, rp);
}
- else
- scm_wrong_type_arg_msg ("exact-integer-sqrt", SCM_ARG1, k,
- "exact non-negative integer");
+ scm_wrong_type_arg_msg ("exact-integer-sqrt", SCM_ARG1, k,
+ "exact non-negative integer");
}
/* Return true iff K is a perfect square.