summaryrefslogtreecommitdiff
path: root/mpz
diff options
context:
space:
mode:
authorMarco Bodrato <bodrato@mail.dm.unipi.it>2021-11-07 23:06:54 +0100
committerMarco Bodrato <bodrato@mail.dm.unipi.it>2021-11-07 23:06:54 +0100
commitc9150dcdb0129066a0baad25a3ea895dfae03fae (patch)
tree1f0d4852bde5d4f8c400c9c6ac17964357dad838 /mpz
parentce133f108cb707ced137ea3aaa2fa12ffb96fcc3 (diff)
downloadgmp-c9150dcdb0129066a0baad25a3ea895dfae03fae.tar.gz
mpz/oddfac_1.c: Save half the products for small values
Diffstat (limited to 'mpz')
-rw-r--r--mpz/oddfac_1.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/mpz/oddfac_1.c b/mpz/oddfac_1.c
index e4da05cbf..9a20ba4ac 100644
--- a/mpz/oddfac_1.c
+++ b/mpz/oddfac_1.c
@@ -258,9 +258,9 @@ mpz_2multiswing_1 (mpz_ptr x, mp_limb_t n, mp_ptr sieve, mp_ptr factors)
/*********************************************************/
#if TUNE_PROGRAM_BUILD
-#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_DSC_THRESHOLD_LIMIT-1)+1))
+#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_DSC_THRESHOLD_LIMIT*FAC_DSC_THRESHOLD_LIMIT-1)+1) * 2)
#else
-#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_DSC_THRESHOLD-1)+1))
+#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_DSC_THRESHOLD*FAC_DSC_THRESHOLD-1)+1) * 2)
#endif
/* mpz_oddfac_1 computes the odd part of the factorial of the
@@ -304,7 +304,7 @@ mpz_oddfac_1 (mpz_ptr x, mp_limb_t n, unsigned flag)
s = 0;
{
mp_limb_t tn;
- mp_limb_t prod, max_prod, i;
+ mp_limb_t prod, max_prod;
mp_size_t j;
TMP_SDECL;
@@ -325,20 +325,31 @@ mpz_oddfac_1 (mpz_ptr x, mp_limb_t n, unsigned flag)
prod = 1;
#if TUNE_PROGRAM_BUILD
- max_prod = GMP_NUMB_MAX / FAC_DSC_THRESHOLD_LIMIT;
+ max_prod = GMP_NUMB_MAX / (FAC_DSC_THRESHOLD_LIMIT * FAC_DSC_THRESHOLD_LIMIT);
#else
- max_prod = GMP_NUMB_MAX / FAC_DSC_THRESHOLD;
+ max_prod = GMP_NUMB_MAX / (FAC_DSC_THRESHOLD * FAC_DSC_THRESHOLD);
#endif
ASSERT (tn > ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1);
do {
- i = ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 2;
factors[j++] = ODD_DOUBLEFACTORIAL_TABLE_MAX;
- do {
- FACTOR_LIST_STORE (i, prod, max_prod, factors, j);
- i += 2;
- } while (i <= tn);
- max_prod <<= 1;
+ mp_limb_t diff = tn - ODD_DOUBLEFACTORIAL_TABLE_LIMIT & -CNST_LIMB (2);
+ if ((diff & 2) != 0)
+ {
+ FACTOR_LIST_STORE (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + diff, prod, max_prod, factors, j);
+ diff -= 2;
+ }
+ if (diff != 0)
+ {
+ mp_limb_t fac = (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 2) *
+ (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + diff);
+ do {
+ FACTOR_LIST_STORE (fac, prod, max_prod, factors, j);
+ diff -= 4;
+ fac += diff * 2;
+ } while (diff != 0);
+ }
+ max_prod <<= 2;
tn >>= 1;
} while (tn > ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1);