diff options
author | Torbjorn Granlund <tege@gmplib.org> | 2011-08-07 21:28:02 +0200 |
---|---|---|
committer | Torbjorn Granlund <tege@gmplib.org> | 2011-08-07 21:28:02 +0200 |
commit | 174d4fd334cb6dce6a09e4ce3edb33bdd19d938a (patch) | |
tree | 996385720c9357186939de8f032050b76c39bcfe /gen-bases.c | |
parent | 385eadb78463524370526fb012f38d037cb3f7fe (diff) | |
download | gmp-174d4fd334cb6dce6a09e4ce3edb33bdd19d938a.tar.gz |
Use integer fields for mp_bases logarithm tables.
Diffstat (limited to 'gen-bases.c')
-rw-r--r-- | gen-bases.c | 98 |
1 files changed, 80 insertions, 18 deletions
diff --git a/gen-bases.c b/gen-bases.c index 31895e8b2..a467c19eb 100644 --- a/gen-bases.c +++ b/gen-bases.c @@ -1,7 +1,7 @@ /* Generate mp_bases data. -Copyright 1991, 1993, 1994, 1996, 2000, 2002, 2004 Free Software Foundation, -Inc. +Copyright 1991, 1993, 1994, 1996, 2000, 2002, 2004, 2011 Free Software +Foundation, Inc. This file is part of the GNU MP Library. @@ -24,7 +24,6 @@ along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ int chars_per_limb; -double chars_per_bit_exactly; mpz_t big_base; int normalization_steps; mpz_t big_base_inverted; @@ -59,8 +58,6 @@ generate (int limb_bits, int nail_bits, int base) chars_per_limb++; } - chars_per_bit_exactly = 0.69314718055994530942 / log ((double) base); - mpz_ui_pow_ui (big_base, (long) base, (long) chars_per_limb); normalization_steps = limb_bits - mpz_sizeinbase (big_base, 2); @@ -97,11 +94,61 @@ header (int limb_bits, int nail_bits) printf ("#define MP_BASES_NORMALIZATION_STEPS_10 %d\n", normalization_steps); } + +#define EXTRA 16 + +/* Compute log(2)/log(b) as a fixnum. */ +void +mp_2logb (mpz_t r, int bi, int prec) +{ + mpz_t t, t2, two, b; + int i; + + mpz_init_set_ui (t, 1); + mpz_mul_2exp (t, t, prec+EXTRA); + + mpz_init (t2); + + mpz_init_set_ui (two, 2); + mpz_mul_2exp (two, two, prec+EXTRA); + + mpz_set_ui (r, 0); + + mpz_init_set_ui (b, bi); + mpz_mul_2exp (b, b, prec+EXTRA); + + for (i = prec-1; i >= 0; i--) + { + mpz_mul_2exp (b, b, prec+EXTRA); + mpz_sqrt (b, b); + + mpz_mul (t2, t, b); + mpz_tdiv_q_2exp (t2, t2, prec+EXTRA); + + if (mpz_cmp (t2, two) < 0) /* not too large? */ + { + mpz_setbit (r, i); /* set next less significant bit */ + mpz_set (t, t2); /* new value acceptable */ + } + } + + mpz_clear (t); + mpz_clear (t2); + mpz_clear (two); + mpz_clear (b); +} + void table (int limb_bits, int nail_bits) { int numb_bits = limb_bits - nail_bits; int base; + mpz_t r, t, logb2, log2b; + + mpz_init (r); + mpz_init (t); + mpz_init (logb2); + mpz_init (log2b); printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n"); printf ("\n"); @@ -113,30 +160,45 @@ table (int limb_bits, int nail_bits) printf ("#endif\n"); printf ("\n"); puts ("const struct bases mp_bases[257] =\n{"); - puts (" /* 0 */ { 0, 0.0, 0 },"); - puts (" /* 1 */ { 0, 1e37, 0 },"); + puts (" /* 0 */ { 0, 0.0, 0, 0, 0, 0 },"); + puts (" /* 1 */ { 0, 1e37, 0, 0, 0, 0 },"); for (base = 2; base <= 256; base++) { generate (limb_bits, nail_bits, base); + mp_2logb (r, base, limb_bits + 8); + mpz_tdiv_q_2exp (logb2, r, 8); + mpz_set_ui (t, 1); + mpz_mul_2exp (t, t, 2*limb_bits + 5); + mpz_sub_ui (t, t, 1); + mpz_add_ui (r, r, 1); + mpz_tdiv_q (log2b, t, r); printf (" /* %3u */ { ", base); if (POW2_P (base)) { - printf ("%u, %.16f, 0x%x },\n", - chars_per_limb, chars_per_bit_exactly, ulog2 (base) - 1); - } - else - { - printf ("%u, %.16f, CNST_LIMB(0x", - chars_per_limb, chars_per_bit_exactly); - mpz_out_str (stdout, 16, big_base); - printf ("), CNST_LIMB(0x"); - mpz_out_str (stdout, 16, big_base_inverted); - printf (") },\n"); + mpz_set_ui (big_base, ulog2 (base) - 1); + mpz_set_ui (big_base_inverted, 0); } + + printf ("%u,", chars_per_limb); + printf (" CNST_LIMB(0x"); + mpz_out_str (stdout, 16, logb2); + printf ("), CNST_LIMB(0x"); + mpz_out_str (stdout, 16, log2b); + printf ("), CNST_LIMB(0x"); + mpz_out_str (stdout, 16, big_base); + printf ("), CNST_LIMB(0x"); + mpz_out_str (stdout, 16, big_base_inverted); + printf (") },\n"); } puts ("};"); + + mpz_clear (r); + mpz_clear (t); + mpz_clear (logb2); + mpz_clear (log2b); + } int |