summaryrefslogtreecommitdiff
path: root/mpz/bin_uiui.c
diff options
context:
space:
mode:
authorMarco Bodrato <bodrato@mail.dm.unipi.it>2012-04-17 08:02:34 +0200
committerMarco Bodrato <bodrato@mail.dm.unipi.it>2012-04-17 08:02:34 +0200
commit3a5fd656ba354687c2c3f7e8a30cbfed3381a30c (patch)
treeb5f8692f93ec17b2825bc3f5768ca1abc3baace7 /mpz/bin_uiui.c
parent29562d58a1a2d7fc2f40a45416b9240a4b6e0996 (diff)
downloadgmp-3a5fd656ba354687c2c3f7e8a30cbfed3381a30c.tar.gz
mpz/bin_uiui.c: Support small limbs (fallback on bin_ui).
Diffstat (limited to 'mpz/bin_uiui.c')
-rw-r--r--mpz/bin_uiui.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/mpz/bin_uiui.c b/mpz/bin_uiui.c
index e99188f5e..82943e4f0 100644
--- a/mpz/bin_uiui.c
+++ b/mpz/bin_uiui.c
@@ -346,6 +346,9 @@ mpz_smallk_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k)
mpn_pi1_bdiv_q_1 (rp, rp, rn, fac[k], facinv[k - 2],
fac2cnt[k / 2 - 1] - i2cnt);
+ /* A two-fold, branch-free normalisation is possible :*/
+ /* rn -= rp[rn - 1] == 0; */
+ /* rn -= rp[rn - 1] == 0; */
MPN_NORMALIZE_NOT_ZERO (rp, rn);
SIZ(r) = rn;
@@ -426,17 +429,27 @@ mpz_smallkdc_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k)
mpn_pi1_bdiv_q_1 (rp, rp, rn, bin2kk[k - ODD_CENTRAL_BINOMIAL_OFFSET],
bin2kkinv[k - ODD_CENTRAL_BINOMIAL_OFFSET],
fac2bin[k - ODD_CENTRAL_BINOMIAL_OFFSET] - (k != hk));
+ /* A two-fold, branch-free normalisation is possible :*/
+ /* rn -= rp[rn - 1] == 0; */
+ /* rn -= rp[rn - 1] == 0; */
MPN_NORMALIZE_NOT_ZERO (rp, rn);
SIZ(r) = rn;
}
-/* WARNING: it assumes that n fits in a limb! */
void
mpz_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k)
{
if (UNLIKELY (n < k)) {
SIZ (r) = 0;
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ } else if (UNLIKELY (n > GMP_NUMB_MAX)) {
+ mpz_t tmp;
+
+ mpz_init_set_ui (tmp, n);
+ mpz_bin_ui (r, tmp, k);
+ mpz_clear (tmp);
+#endif
} else {
ASSERT (n <= GMP_NUMB_MAX);
/* Rewrite bin(n,k) as bin(n,n-k) if that is smaller. */