[Gmp-commit] /var/hg/gmp: mpz/bin_uiui.c (mpz_bdiv_bin_uiui): Use precomputed...
mercurial at gmplib.org
mercurial at gmplib.org
Mon Apr 16 07:38:33 CEST 2012
details: /var/hg/gmp/rev/1e4085291ae4
changeset: 14835:1e4085291ae4
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Mon Apr 16 07:35:54 2012 +0200
description:
mpz/bin_uiui.c (mpz_bdiv_bin_uiui): Use precomputed factorials to init.
diffstat:
mpz/bin_uiui.c | 60 +++++++++++++++++++++++++++++++--------------------------
1 files changed, 33 insertions(+), 27 deletions(-)
diffs (114 lines):
diff -r aa3f6b4acebe -r 1e4085291ae4 mpz/bin_uiui.c
--- a/mpz/bin_uiui.c Mon Apr 16 00:37:12 2012 +0200
+++ b/mpz/bin_uiui.c Mon Apr 16 07:35:54 2012 +0200
@@ -180,6 +180,17 @@
} while (0)
#endif
+/* Entry i contains (i!/2^t) where t is chosen such that the parenthesis
+ is an odd integer. */
+static const mp_limb_t fac[] = { ONE_LIMB_ODD_FACTORIAL_TABLE, ONE_LIMB_ODD_FACTORIAL_EXTTABLE };
+
+/* Entry i contains (i!/2^t)^(-1) where t is chosen such that the parenthesis
+ is an odd integer. */
+static const mp_limb_t facinv[] = { ONE_LIMB_ODD_FACTORIAL_INVERSES_TABLE };
+
+/* Entry i contains 2i-popc(2i). */
+static const unsigned char fac2cnt[] = { TABLE_2N_MINUS_POPC_2N };
+
static void
mpz_bdiv_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k)
{
@@ -192,6 +203,7 @@
mp_size_t maxn;
TMP_DECL;
+ ASSERT (k > ODD_FACTORIAL_TABLE_LIMIT);
TMP_MARK;
maxn = 1 + n / GMP_NUMB_BITS; /* absolutely largest result size (limbs) */
@@ -204,30 +216,25 @@
kp = TMP_ALLOC_LIMBS (SOME_THRESHOLD + 1);
MAXFACS (nmax, n);
- nmax = MIN (nmax, M);
+ ASSERT (nmax <= M);
MAXFACS (kmax, k);
- kmax = MIN (kmax, M);
+ ASSERT (kmax <= M);
+ ASSERT (k >= M);
- j = 1;
i = n - k + 1;
- nmax = MIN (nmax, k);
- kmax = MIN (kmax, k);
-
np[0] = 1; nn = 1;
i2cnt = 0; /* total low zeros in dividend */
- j2cnt = 0; /* total low zeros in divisor */
+ j2cnt = fac2cnt[ODD_FACTORIAL_TABLE_LIMIT / 2 - 1];
+ /* total low zeros in divisor */
- while (kmax != 0)
+ numfac = 1;
+ j = ODD_FACTORIAL_TABLE_LIMIT + 1;
+ jjj = fac[ODD_FACTORIAL_TABLE_LIMIT];
+
+ while (1)
{
- numfac = j;
-
- jjj = mulfunc[kmax] (j);
- j += kmax; /* number of factors used */
- count_trailing_zeros (cnt, jjj); /* count low zeros */
- jjj >>= cnt; /* remove remaining low zeros */
- j2cnt += tcnttab[kmax] + cnt; /* update low zeros count */
kp[0] = jjj; /* store new factors */
kn = 1;
t = k - j + 1;
@@ -268,6 +275,16 @@
nn += (np[nn - 1] >= kp[kn - 1]);
nn -= kn;
mpn_sbpi1_bdiv_q (np, np, nn, kp, MIN(kn,nn), -dinv);
+
+ if (kmax == 0)
+ break;
+ numfac = j;
+
+ jjj = mulfunc[kmax] (j);
+ j += kmax; /* number of factors used */
+ count_trailing_zeros (cnt, jjj); /* count low zeros */
+ jjj >>= cnt; /* remove remaining low zeros */
+ j2cnt += tcnttab[kmax] + cnt; /* update low zeros count */
}
/* Put back the right number of factors of 2. */
@@ -288,17 +305,6 @@
TMP_FREE;
}
-/* Entry i contains (i!/2^t) where t is chosen such that the parenthesis
- is an odd integer. */
-static const mp_limb_t fac[] = { ONE_LIMB_ODD_FACTORIAL_TABLE, ONE_LIMB_ODD_FACTORIAL_EXTTABLE };
-
-/* Entry i contains (i!/2^t)^(-1) where t is chosen such that the parenthesis
- is an odd integer. */
-static const mp_limb_t facinv[] = { ONE_LIMB_ODD_FACTORIAL_INVERSES_TABLE };
-
-/* Entry i contains 2i-popc(2i). */
-static const unsigned char fac2cnt[] = { TABLE_2N_MINUS_POPC_2N };
-
static void
mpz_smallk_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k)
{
@@ -446,7 +452,7 @@
else if (BIN_UIUI_ENABLE_SMALLDC &&
k <= (BIN_UIUI_RECURSIVE_SMALLDC ? ODD_CENTRAL_BINOMIAL_TABLE_LIMIT : ODD_FACTORIAL_TABLE_LIMIT)* 2)
mpz_smallkdc_bin_uiui (r, n, k);
- else
+ else /* k > ODD_FACTORIAL_TABLE_LIMIT */
mpz_bdiv_bin_uiui (r, n, k);
}
}
More information about the gmp-commit
mailing list