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 |