| OLD | NEW |
| (Empty) |
| 1 /* Generate mp_bases data. | |
| 2 | |
| 3 Copyright 1991, 1993, 1994, 1996, 2000, 2002, 2004 Free Software Foundation, | |
| 4 Inc. | |
| 5 | |
| 6 This file is part of the GNU MP Library. | |
| 7 | |
| 8 The GNU MP Library is free software; you can redistribute it and/or modify | |
| 9 it under the terms of the GNU Lesser General Public License as published by | |
| 10 the Free Software Foundation; either version 3 of the License, or (at your | |
| 11 option) any later version. | |
| 12 | |
| 13 The GNU MP Library is distributed in the hope that it will be useful, but | |
| 14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
| 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |
| 16 License for more details. | |
| 17 | |
| 18 You should have received a copy of the GNU Lesser General Public License | |
| 19 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ | |
| 20 | |
| 21 #include <math.h> | |
| 22 | |
| 23 #include "dumbmp.c" | |
| 24 | |
| 25 | |
| 26 int chars_per_limb; | |
| 27 double chars_per_bit_exactly; | |
| 28 mpz_t big_base; | |
| 29 int normalization_steps; | |
| 30 mpz_t big_base_inverted; | |
| 31 | |
| 32 mpz_t t; | |
| 33 | |
| 34 #define POW2_P(n) (((n) & ((n) - 1)) == 0) | |
| 35 | |
| 36 unsigned int | |
| 37 ulog2 (unsigned int x) | |
| 38 { | |
| 39 unsigned int i; | |
| 40 for (i = 0; x != 0; i++) | |
| 41 x >>= 1; | |
| 42 return i; | |
| 43 } | |
| 44 | |
| 45 void | |
| 46 generate (int limb_bits, int nail_bits, int base) | |
| 47 { | |
| 48 int numb_bits = limb_bits - nail_bits; | |
| 49 | |
| 50 mpz_set_ui (t, 1L); | |
| 51 mpz_mul_2exp (t, t, numb_bits); | |
| 52 mpz_set_ui (big_base, 1L); | |
| 53 chars_per_limb = 0; | |
| 54 for (;;) | |
| 55 { | |
| 56 mpz_mul_ui (big_base, big_base, (long) base); | |
| 57 if (mpz_cmp (big_base, t) > 0) | |
| 58 break; | |
| 59 chars_per_limb++; | |
| 60 } | |
| 61 | |
| 62 chars_per_bit_exactly = 0.69314718055994530942 / log ((double) base); | |
| 63 | |
| 64 mpz_ui_pow_ui (big_base, (long) base, (long) chars_per_limb); | |
| 65 | |
| 66 normalization_steps = limb_bits - mpz_sizeinbase (big_base, 2); | |
| 67 | |
| 68 mpz_set_ui (t, 1L); | |
| 69 mpz_mul_2exp (t, t, 2*limb_bits - normalization_steps); | |
| 70 mpz_tdiv_q (big_base_inverted, t, big_base); | |
| 71 mpz_set_ui (t, 1L); | |
| 72 mpz_mul_2exp (t, t, limb_bits); | |
| 73 mpz_sub (big_base_inverted, big_base_inverted, t); | |
| 74 } | |
| 75 | |
| 76 void | |
| 77 header (int limb_bits, int nail_bits) | |
| 78 { | |
| 79 int numb_bits = limb_bits - nail_bits; | |
| 80 | |
| 81 generate (limb_bits, nail_bits, 10); | |
| 82 | |
| 83 printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n"); | |
| 84 printf ("\n"); | |
| 85 printf ("#if GMP_NUMB_BITS != %d\n", numb_bits); | |
| 86 printf ("Error, error, this data is for %d bits\n", numb_bits); | |
| 87 printf ("#endif\n"); | |
| 88 printf ("\n"); | |
| 89 printf ("/* mp_bases[10] data, as literal values */\n"); | |
| 90 printf ("#define MP_BASES_CHARS_PER_LIMB_10 %d\n", chars_per_limb); | |
| 91 printf ("#define MP_BASES_BIG_BASE_10 CNST_LIMB(0x"); | |
| 92 mpz_out_str (stdout, 16, big_base); | |
| 93 printf (")\n"); | |
| 94 printf ("#define MP_BASES_BIG_BASE_INVERTED_10 CNST_LIMB(0x"); | |
| 95 mpz_out_str (stdout, 16, big_base_inverted); | |
| 96 printf (")\n"); | |
| 97 printf ("#define MP_BASES_NORMALIZATION_STEPS_10 %d\n", normalization_steps); | |
| 98 } | |
| 99 | |
| 100 void | |
| 101 table (int limb_bits, int nail_bits) | |
| 102 { | |
| 103 int numb_bits = limb_bits - nail_bits; | |
| 104 int base; | |
| 105 | |
| 106 printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n"); | |
| 107 printf ("\n"); | |
| 108 printf ("#include \"gmp.h\"\n"); | |
| 109 printf ("#include \"gmp-impl.h\"\n"); | |
| 110 printf ("\n"); | |
| 111 printf ("#if GMP_NUMB_BITS != %d\n", numb_bits); | |
| 112 printf ("Error, error, this data is for %d bits\n", numb_bits); | |
| 113 printf ("#endif\n"); | |
| 114 printf ("\n"); | |
| 115 puts ("const struct bases mp_bases[257] =\n{"); | |
| 116 puts (" /* 0 */ { 0, 0.0, 0 },"); | |
| 117 puts (" /* 1 */ { 0, 1e37, 0 },"); | |
| 118 for (base = 2; base <= 256; base++) | |
| 119 { | |
| 120 generate (limb_bits, nail_bits, base); | |
| 121 | |
| 122 printf (" /* %3u */ { ", base); | |
| 123 if (POW2_P (base)) | |
| 124 { | |
| 125 printf ("%u, %.16f, 0x%x },\n", | |
| 126 chars_per_limb, chars_per_bit_exactly, ulog2 (base) - 1); | |
| 127 } | |
| 128 else | |
| 129 { | |
| 130 printf ("%u, %.16f, CNST_LIMB(0x", | |
| 131 chars_per_limb, chars_per_bit_exactly); | |
| 132 mpz_out_str (stdout, 16, big_base); | |
| 133 printf ("), CNST_LIMB(0x"); | |
| 134 mpz_out_str (stdout, 16, big_base_inverted); | |
| 135 printf (") },\n"); | |
| 136 } | |
| 137 } | |
| 138 | |
| 139 puts ("};"); | |
| 140 } | |
| 141 | |
| 142 int | |
| 143 main (int argc, char **argv) | |
| 144 { | |
| 145 int limb_bits, nail_bits; | |
| 146 | |
| 147 mpz_init (big_base); | |
| 148 mpz_init (big_base_inverted); | |
| 149 mpz_init (t); | |
| 150 | |
| 151 if (argc != 4) | |
| 152 { | |
| 153 fprintf (stderr, "Usage: gen-bases <header|table> <limbbits> <nailbits>\n"
); | |
| 154 exit (1); | |
| 155 } | |
| 156 | |
| 157 limb_bits = atoi (argv[2]); | |
| 158 nail_bits = atoi (argv[3]); | |
| 159 | |
| 160 if (limb_bits <= 0 | |
| 161 || nail_bits < 0 | |
| 162 || nail_bits >= limb_bits) | |
| 163 { | |
| 164 fprintf (stderr, "Invalid limb/nail bits: %d %d\n", | |
| 165 limb_bits, nail_bits); | |
| 166 exit (1); | |
| 167 } | |
| 168 | |
| 169 if (strcmp (argv[1], "header") == 0) | |
| 170 header (limb_bits, nail_bits); | |
| 171 else if (strcmp (argv[1], "table") == 0) | |
| 172 table (limb_bits, nail_bits); | |
| 173 else | |
| 174 { | |
| 175 fprintf (stderr, "Invalid header/table choice: %s\n", argv[1]); | |
| 176 exit (1); | |
| 177 } | |
| 178 | |
| 179 return 0; | |
| 180 } | |
| OLD | NEW |