diff options
author | Andy Wingo <wingo@pobox.com> | 2022-01-06 22:07:20 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2022-01-13 09:37:17 +0100 |
commit | 63a18a6c1a2eae570c5de2b9eb866b20bc5e5e5e (patch) | |
tree | a6dbda388456eb168061d28607e7e1754564735d /libguile/integers.c | |
parent | 9a91c20a551484f6a71bb35fa47b10f75f502c74 (diff) | |
download | guile-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.c | 30 |
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); +} |