[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 56/69: Reimplement exact-integer-sqrt with integers.[ch]
From: |
Andy Wingo |
Subject: |
[Guile-commits] 56/69: Reimplement exact-integer-sqrt with integers.[ch] |
Date: |
Fri, 7 Jan 2022 08:27:20 -0500 (EST) |
wingo pushed a commit to branch wip-inline-digits
in repository guile.
commit 84e5ad44bad2b93ddb821ec70a394dd800d053d5
Author: Andy Wingo <wingo@pobox.com>
AuthorDate: Thu Jan 6 22:07:20 2022 +0100
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.
---
libguile/integers.c | 30 ++++++++++++++++++++++++++++++
libguile/integers.h | 4 ++++
libguile/numbers.c | 41 ++++++++++-------------------------------
3 files changed, 44 insertions(+), 31 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);
+}
diff --git a/libguile/integers.h b/libguile/integers.h
index e48db1d17..1bba509ea 100644
--- a/libguile/integers.h
+++ b/libguile/integers.h
@@ -212,6 +212,10 @@ SCM_INTERNAL int scm_integer_to_uint64_z (struct
scm_bignum *z, uint64_t *val);
SCM_INTERNAL SCM scm_integer_from_int64 (int64_t n);
SCM_INTERNAL SCM scm_integer_from_uint64 (uint64_t n);
+SCM_INTERNAL void scm_integer_exact_sqrt_i (scm_t_inum k, SCM *s, SCM *r);
+SCM_INTERNAL void scm_integer_exact_sqrt_z (struct scm_bignum *k,
+ SCM *s, SCM *r);
+
#endif /* SCM_INTEGERS_H */
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.
- [Guile-commits] 53/69: Implement scm_{to,from}_wchar inline, (continued)
- [Guile-commits] 53/69: Implement scm_{to,from}_wchar inline, Andy Wingo, 2022/01/07
- [Guile-commits] 60/69: divide2double refactor, Andy Wingo, 2022/01/07
- [Guile-commits] 65/69: Avoid scm_i_mkbig outside numbers.c., Andy Wingo, 2022/01/07
- [Guile-commits] 57/69: Refactor scm_sqrt in terms of integers.[ch], Andy Wingo, 2022/01/07
- [Guile-commits] 59/69: Remove dead bignum frexp code from numbers.c, Andy Wingo, 2022/01/07
- [Guile-commits] 47/69: Fix deprecated bit-count* when counting 0 bits, Andy Wingo, 2022/01/07
- [Guile-commits] 49/69: Reimplement scm_is_{un, }signed_integer for bignums, Andy Wingo, 2022/01/07
- [Guile-commits] 51/69: Reimplement scm_{to,from}_{int32,uint32}, Andy Wingo, 2022/01/07
- [Guile-commits] 45/69: Remove support for allowing exact numbers to be divided by zero, Andy Wingo, 2022/01/07
- [Guile-commits] 50/69: Reimplement scm_from_int8 etc, Andy Wingo, 2022/01/07
- [Guile-commits] 56/69: Reimplement exact-integer-sqrt with integers.[ch],
Andy Wingo <=
- [Guile-commits] 55/69: scm_to_mpz uses integer lib, Andy Wingo, 2022/01/07
- [Guile-commits] 62/69: Remove last non-admin SCM_I_BIG_MPZ uses in numbers.c, Andy Wingo, 2022/01/07
- [Guile-commits] 61/69: Simplify scm_exact_integer_quotient, Andy Wingo, 2022/01/07
- [Guile-commits] 63/69: Simplify magnitude, angle, Andy Wingo, 2022/01/07
- [Guile-commits] 64/69: Use scm_integer_to_double_z in numbers.c instead of big2dbl, Andy Wingo, 2022/01/07
- [Guile-commits] 67/69: Finish srfi-60 port off old scm mpz API, Andy Wingo, 2022/01/07
- [Guile-commits] 66/69: Start porting srfi-60 off the bad bignum interfaces, Andy Wingo, 2022/01/07
- [Guile-commits] 69/69: Bignums avoid both custom GMP allocator and finalizers, Andy Wingo, 2022/01/07
- [Guile-commits] 68/69: scm_to_ipv6 uses scm_to_mpz, Andy Wingo, 2022/01/07