summaryrefslogtreecommitdiff
path: root/libguile/integers.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/integers.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/integers.c')
-rw-r--r--libguile/integers.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/libguile/integers.c b/libguile/integers.c
index 0ca799b9e..d318fd775 100644
--- a/libguile/integers.c
+++ b/libguile/integers.c
@@ -3044,3 +3044,33 @@ scm_integer_to_mpz_z (struct scm_bignum *z, mpz_t n)
mpz_init_set (n, zn);
scm_remember_upto_here_1 (z);
}
+
+void
+scm_integer_exact_sqrt_i (scm_t_inum k, SCM *s, SCM *r)
+{
+ ASSERT (k >= 0);
+ if (k == 0)
+ *s = *r = SCM_INUM0;
+ else
+ {
+ mp_limb_t kk = k, ss, rr;
+ if (mpn_sqrtrem (&ss, &rr, &kk, 1) == 0)
+ rr = 0;
+ *s = SCM_I_MAKINUM (ss);
+ *r = SCM_I_MAKINUM (rr);
+ }
+}
+
+void
+scm_integer_exact_sqrt_z (struct scm_bignum *k, SCM *s, SCM *r)
+{
+ mpz_t zk, zs, zr;
+ alias_bignum_to_mpz (k, zk);
+ mpz_init (zs);
+ mpz_init (zr);
+
+ mpz_sqrtrem (zs, zr, zk);
+ scm_remember_upto_here_1 (k);
+ *s = take_mpz (zs);
+ *r = take_mpz (zr);
+}