summaryrefslogtreecommitdiff
path: root/gen-bases.c
diff options
context:
space:
mode:
authorTorbjorn Granlund <tege@gmplib.org>2011-08-07 21:28:02 +0200
committerTorbjorn Granlund <tege@gmplib.org>2011-08-07 21:28:02 +0200
commit174d4fd334cb6dce6a09e4ce3edb33bdd19d938a (patch)
tree996385720c9357186939de8f032050b76c39bcfe /gen-bases.c
parent385eadb78463524370526fb012f38d037cb3f7fe (diff)
downloadgmp-174d4fd334cb6dce6a09e4ce3edb33bdd19d938a.tar.gz
Use integer fields for mp_bases logarithm tables.
Diffstat (limited to 'gen-bases.c')
-rw-r--r--gen-bases.c98
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