get_str.c revision 1.1 1 1.1 mrg /* mpn_get_str -- Convert {UP,USIZE} to a base BASE string in STR.
2 1.1 mrg
3 1.1 mrg Contributed to the GNU project by Torbjorn Granlund.
4 1.1 mrg
5 1.1 mrg THE FUNCTIONS IN THIS FILE, EXCEPT mpn_get_str, ARE INTERNAL WITH A MUTABLE
6 1.1 mrg INTERFACE. IT IS ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN
7 1.1 mrg FACT, IT IS ALMOST GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE
8 1.1 mrg GNU MP RELEASE.
9 1.1 mrg
10 1.1 mrg Copyright 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002, 2004, 2006, 2007,
11 1.1 mrg 2008 Free Software Foundation, Inc.
12 1.1 mrg
13 1.1 mrg This file is part of the GNU MP Library.
14 1.1 mrg
15 1.1 mrg The GNU MP Library is free software; you can redistribute it and/or modify
16 1.1 mrg it under the terms of the GNU Lesser General Public License as published by
17 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your
18 1.1 mrg option) any later version.
19 1.1 mrg
20 1.1 mrg The GNU MP Library is distributed in the hope that it will be useful, but
21 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
23 1.1 mrg License for more details.
24 1.1 mrg
25 1.1 mrg You should have received a copy of the GNU Lesser General Public License
26 1.1 mrg along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
27 1.1 mrg
28 1.1 mrg #include "gmp.h"
29 1.1 mrg #include "gmp-impl.h"
30 1.1 mrg #include "longlong.h"
31 1.1 mrg
32 1.1 mrg /* Conversion of U {up,un} to a string in base b. Internally, we convert to
33 1.1 mrg base B = b^m, the largest power of b that fits a limb. Basic algorithms:
34 1.1 mrg
35 1.1 mrg A) Divide U repeatedly by B, generating a quotient and remainder, until the
36 1.1 mrg quotient becomes zero. The remainders hold the converted digits. Digits
37 1.1 mrg come out from right to left. (Used in mpn_sb_get_str.)
38 1.1 mrg
39 1.1 mrg B) Divide U by b^g, for g such that 1/b <= U/b^g < 1, generating a fraction.
40 1.1 mrg Then develop digits by multiplying the fraction repeatedly by b. Digits
41 1.1 mrg come out from left to right. (Currently not used herein, except for in
42 1.1 mrg code for converting single limbs to individual digits.)
43 1.1 mrg
44 1.1 mrg C) Compute B^1, B^2, B^4, ..., B^s, for s such that B^s is just above
45 1.1 mrg sqrt(U). Then divide U by B^s, generating quotient and remainder.
46 1.1 mrg Recursively convert the quotient, then the remainder, using the
47 1.1 mrg precomputed powers. Digits come out from left to right. (Used in
48 1.1 mrg mpn_dc_get_str.)
49 1.1 mrg
50 1.1 mrg When using algorithm C, algorithm B might be suitable for basecase code,
51 1.1 mrg since the required b^g power will be readily accessible.
52 1.1 mrg
53 1.1 mrg Optimization ideas:
54 1.1 mrg 1. The recursive function of (C) could use less temporary memory. The powtab
55 1.1 mrg allocation could be trimmed with some computation, and the tmp area could
56 1.1 mrg be reduced, or perhaps eliminated if up is reused for both quotient and
57 1.1 mrg remainder (it is currently used just for remainder).
58 1.1 mrg 2. Store the powers of (C) in normalized form, with the normalization count.
59 1.1 mrg Quotients will usually need to be left-shifted before each divide, and
60 1.1 mrg remainders will either need to be left-shifted of right-shifted.
61 1.1 mrg 3. In the code for developing digits from a single limb, we could avoid using
62 1.1 mrg a full umul_ppmm except for the first (or first few) digits, provided base
63 1.1 mrg is even. Subsequent digits can be developed using plain multiplication.
64 1.1 mrg (This saves on register-starved machines (read x86) and on all machines
65 1.1 mrg that generate the upper product half using a separate instruction (alpha,
66 1.1 mrg powerpc, IA-64) or lacks such support altogether (sparc64, hppa64).
67 1.1 mrg 4. Separate mpn_dc_get_str basecase code from code for small conversions. The
68 1.1 mrg former code will have the exact right power readily available in the
69 1.1 mrg powtab parameter for dividing the current number into a fraction. Convert
70 1.1 mrg that using algorithm B.
71 1.1 mrg 5. Completely avoid division. Compute the inverses of the powers now in
72 1.1 mrg powtab instead of the actual powers.
73 1.1 mrg 6. Decrease powtab allocation for even bases. E.g. for base 10 we could save
74 1.1 mrg about 30% (1-log(5)/log(10)).
75 1.1 mrg
76 1.1 mrg Basic structure of (C):
77 1.1 mrg mpn_get_str:
78 1.1 mrg if POW2_P (n)
79 1.1 mrg ...
80 1.1 mrg else
81 1.1 mrg if (un < GET_STR_PRECOMPUTE_THRESHOLD)
82 1.1 mrg mpn_sb_get_str (str, base, up, un);
83 1.1 mrg else
84 1.1 mrg precompute_power_tables
85 1.1 mrg mpn_dc_get_str
86 1.1 mrg
87 1.1 mrg mpn_dc_get_str:
88 1.1 mrg mpn_tdiv_qr
89 1.1 mrg if (qn < GET_STR_DC_THRESHOLD)
90 1.1 mrg mpn_sb_get_str
91 1.1 mrg else
92 1.1 mrg mpn_dc_get_str
93 1.1 mrg if (rn < GET_STR_DC_THRESHOLD)
94 1.1 mrg mpn_sb_get_str
95 1.1 mrg else
96 1.1 mrg mpn_dc_get_str
97 1.1 mrg
98 1.1 mrg
99 1.1 mrg The reason for the two threshold values is the cost of
100 1.1 mrg precompute_power_tables. GET_STR_PRECOMPUTE_THRESHOLD will be considerably
101 1.1 mrg larger than GET_STR_PRECOMPUTE_THRESHOLD. */
102 1.1 mrg
103 1.1 mrg
104 1.1 mrg /* The x86s and m68020 have a quotient and remainder "div" instruction and
105 1.1 mrg gcc recognises an adjacent "/" and "%" can be combined using that.
106 1.1 mrg Elsewhere "/" and "%" are either separate instructions, or separate
107 1.1 mrg libgcc calls (which unfortunately gcc as of version 3.0 doesn't combine).
108 1.1 mrg A multiply and subtract should be faster than a "%" in those cases. */
109 1.1 mrg #if HAVE_HOST_CPU_FAMILY_x86 \
110 1.1 mrg || HAVE_HOST_CPU_m68020 \
111 1.1 mrg || HAVE_HOST_CPU_m68030 \
112 1.1 mrg || HAVE_HOST_CPU_m68040 \
113 1.1 mrg || HAVE_HOST_CPU_m68060 \
114 1.1 mrg || HAVE_HOST_CPU_m68360 /* CPU32 */
115 1.1 mrg #define udiv_qrnd_unnorm(q,r,n,d) \
116 1.1 mrg do { \
117 1.1 mrg mp_limb_t __q = (n) / (d); \
118 1.1 mrg mp_limb_t __r = (n) % (d); \
119 1.1 mrg (q) = __q; \
120 1.1 mrg (r) = __r; \
121 1.1 mrg } while (0)
122 1.1 mrg #else
123 1.1 mrg #define udiv_qrnd_unnorm(q,r,n,d) \
124 1.1 mrg do { \
125 1.1 mrg mp_limb_t __q = (n) / (d); \
126 1.1 mrg mp_limb_t __r = (n) - __q*(d); \
127 1.1 mrg (q) = __q; \
128 1.1 mrg (r) = __r; \
129 1.1 mrg } while (0)
130 1.1 mrg #endif
131 1.1 mrg
132 1.1 mrg
133 1.1 mrg /* Convert {up,un} to a string in base base, and put the result in str.
135 1.1 mrg Generate len characters, possibly padding with zeros to the left. If len is
136 1.1 mrg zero, generate as many characters as required. Return a pointer immediately
137 1.1 mrg after the last digit of the result string. Complexity is O(un^2); intended
138 1.1 mrg for small conversions. */
139 1.1 mrg static unsigned char *
140 1.1 mrg mpn_sb_get_str (unsigned char *str, size_t len,
141 1.1 mrg mp_ptr up, mp_size_t un, int base)
142 1.1 mrg {
143 1.1 mrg mp_limb_t rl, ul;
144 1.1 mrg unsigned char *s;
145 1.1 mrg size_t l;
146 1.1 mrg /* Allocate memory for largest possible string, given that we only get here
147 1.1 mrg for operands with un < GET_STR_PRECOMPUTE_THRESHOLD and that the smallest
148 1.1 mrg base is 3. 7/11 is an approximation to 1/log2(3). */
149 1.1 mrg #if TUNE_PROGRAM_BUILD
150 1.1 mrg #define BUF_ALLOC (GET_STR_THRESHOLD_LIMIT * GMP_LIMB_BITS * 7 / 11)
151 1.1 mrg #else
152 1.1 mrg #define BUF_ALLOC (GET_STR_PRECOMPUTE_THRESHOLD * GMP_LIMB_BITS * 7 / 11)
153 1.1 mrg #endif
154 1.1 mrg unsigned char buf[BUF_ALLOC];
155 1.1 mrg #if TUNE_PROGRAM_BUILD
156 1.1 mrg mp_limb_t rp[GET_STR_THRESHOLD_LIMIT];
157 1.1 mrg #else
158 1.1 mrg mp_limb_t rp[GET_STR_PRECOMPUTE_THRESHOLD];
159 1.1 mrg #endif
160 1.1 mrg
161 1.1 mrg if (base == 10)
162 1.1 mrg {
163 1.1 mrg /* Special case code for base==10 so that the compiler has a chance to
164 1.1 mrg optimize things. */
165 1.1 mrg
166 1.1 mrg MPN_COPY (rp + 1, up, un);
167 1.1 mrg
168 1.1 mrg s = buf + BUF_ALLOC;
169 1.1 mrg while (un > 1)
170 1.1 mrg {
171 1.1 mrg int i;
172 1.1 mrg mp_limb_t frac, digit;
173 1.1 mrg MPN_DIVREM_OR_PREINV_DIVREM_1 (rp, (mp_size_t) 1, rp + 1, un,
174 1.1 mrg MP_BASES_BIG_BASE_10,
175 1.1 mrg MP_BASES_BIG_BASE_INVERTED_10,
176 1.1 mrg MP_BASES_NORMALIZATION_STEPS_10);
177 1.1 mrg un -= rp[un] == 0;
178 1.1 mrg frac = (rp[0] + 1) << GMP_NAIL_BITS;
179 1.1 mrg s -= MP_BASES_CHARS_PER_LIMB_10;
180 1.1 mrg #if HAVE_HOST_CPU_FAMILY_x86
181 1.1 mrg /* The code below turns out to be a bit slower for x86 using gcc.
182 1.1 mrg Use plain code. */
183 1.1 mrg i = MP_BASES_CHARS_PER_LIMB_10;
184 1.1 mrg do
185 1.1 mrg {
186 1.1 mrg umul_ppmm (digit, frac, frac, 10);
187 1.1 mrg *s++ = digit;
188 1.1 mrg }
189 1.1 mrg while (--i);
190 1.1 mrg #else
191 1.1 mrg /* Use the fact that 10 in binary is 1010, with the lowest bit 0.
192 1.1 mrg After a few umul_ppmm, we will have accumulated enough low zeros
193 1.1 mrg to use a plain multiply. */
194 1.1 mrg if (MP_BASES_NORMALIZATION_STEPS_10 == 0)
195 1.1 mrg {
196 1.1 mrg umul_ppmm (digit, frac, frac, 10);
197 1.1 mrg *s++ = digit;
198 1.1 mrg }
199 1.1 mrg if (MP_BASES_NORMALIZATION_STEPS_10 <= 1)
200 1.1 mrg {
201 1.1 mrg umul_ppmm (digit, frac, frac, 10);
202 1.1 mrg *s++ = digit;
203 1.1 mrg }
204 1.1 mrg if (MP_BASES_NORMALIZATION_STEPS_10 <= 2)
205 1.1 mrg {
206 1.1 mrg umul_ppmm (digit, frac, frac, 10);
207 1.1 mrg *s++ = digit;
208 1.1 mrg }
209 1.1 mrg if (MP_BASES_NORMALIZATION_STEPS_10 <= 3)
210 1.1 mrg {
211 1.1 mrg umul_ppmm (digit, frac, frac, 10);
212 1.1 mrg *s++ = digit;
213 1.1 mrg }
214 1.1 mrg i = (MP_BASES_CHARS_PER_LIMB_10 - ((MP_BASES_NORMALIZATION_STEPS_10 < 4)
215 1.1 mrg ? (4-MP_BASES_NORMALIZATION_STEPS_10)
216 1.1 mrg : 0));
217 1.1 mrg frac = (frac + 0xf) >> 4;
218 1.1 mrg do
219 1.1 mrg {
220 1.1 mrg frac *= 10;
221 1.1 mrg digit = frac >> (GMP_LIMB_BITS - 4);
222 1.1 mrg *s++ = digit;
223 1.1 mrg frac &= (~(mp_limb_t) 0) >> 4;
224 1.1 mrg }
225 1.1 mrg while (--i);
226 1.1 mrg #endif
227 1.1 mrg s -= MP_BASES_CHARS_PER_LIMB_10;
228 1.1 mrg }
229 1.1 mrg
230 1.1 mrg ul = rp[1];
231 1.1 mrg while (ul != 0)
232 1.1 mrg {
233 1.1 mrg udiv_qrnd_unnorm (ul, rl, ul, 10);
234 1.1 mrg *--s = rl;
235 1.1 mrg }
236 1.1 mrg }
237 1.1 mrg else /* not base 10 */
238 1.1 mrg {
239 1.1 mrg unsigned chars_per_limb;
240 1.1 mrg mp_limb_t big_base, big_base_inverted;
241 1.1 mrg unsigned normalization_steps;
242 1.1 mrg
243 1.1 mrg chars_per_limb = mp_bases[base].chars_per_limb;
244 1.1 mrg big_base = mp_bases[base].big_base;
245 1.1 mrg big_base_inverted = mp_bases[base].big_base_inverted;
246 1.1 mrg count_leading_zeros (normalization_steps, big_base);
247 1.1 mrg
248 1.1 mrg MPN_COPY (rp + 1, up, un);
249 1.1 mrg
250 1.1 mrg s = buf + BUF_ALLOC;
251 1.1 mrg while (un > 1)
252 1.1 mrg {
253 1.1 mrg int i;
254 1.1 mrg mp_limb_t frac;
255 1.1 mrg MPN_DIVREM_OR_PREINV_DIVREM_1 (rp, (mp_size_t) 1, rp + 1, un,
256 1.1 mrg big_base, big_base_inverted,
257 1.1 mrg normalization_steps);
258 1.1 mrg un -= rp[un] == 0;
259 1.1 mrg frac = (rp[0] + 1) << GMP_NAIL_BITS;
260 1.1 mrg s -= chars_per_limb;
261 1.1 mrg i = chars_per_limb;
262 1.1 mrg do
263 1.1 mrg {
264 1.1 mrg mp_limb_t digit;
265 1.1 mrg umul_ppmm (digit, frac, frac, base);
266 1.1 mrg *s++ = digit;
267 1.1 mrg }
268 1.1 mrg while (--i);
269 1.1 mrg s -= chars_per_limb;
270 1.1 mrg }
271 1.1 mrg
272 1.1 mrg ul = rp[1];
273 1.1 mrg while (ul != 0)
274 1.1 mrg {
275 1.1 mrg udiv_qrnd_unnorm (ul, rl, ul, base);
276 1.1 mrg *--s = rl;
277 1.1 mrg }
278 1.1 mrg }
279 1.1 mrg
280 1.1 mrg l = buf + BUF_ALLOC - s;
281 1.1 mrg while (l < len)
282 1.1 mrg {
283 1.1 mrg *str++ = 0;
284 1.1 mrg len--;
285 1.1 mrg }
286 1.1 mrg while (l != 0)
287 1.1 mrg {
288 1.1 mrg *str++ = *s++;
289 1.1 mrg l--;
290 1.1 mrg }
291 1.1 mrg return str;
292 1.1 mrg }
293 1.1 mrg
294 1.1 mrg
295 1.1 mrg /* Convert {UP,UN} to a string with a base as represented in POWTAB, and put
297 1.1 mrg the string in STR. Generate LEN characters, possibly padding with zeros to
298 1.1 mrg the left. If LEN is zero, generate as many characters as required.
299 1.1 mrg Return a pointer immediately after the last digit of the result string.
300 1.1 mrg This uses divide-and-conquer and is intended for large conversions. */
301 1.1 mrg static unsigned char *
302 1.1 mrg mpn_dc_get_str (unsigned char *str, size_t len,
303 1.1 mrg mp_ptr up, mp_size_t un,
304 1.1 mrg const powers_t *powtab, mp_ptr tmp)
305 1.1 mrg {
306 1.1 mrg if (BELOW_THRESHOLD (un, GET_STR_DC_THRESHOLD))
307 1.1 mrg {
308 1.1 mrg if (un != 0)
309 1.1 mrg str = mpn_sb_get_str (str, len, up, un, powtab->base);
310 1.1 mrg else
311 1.1 mrg {
312 1.1 mrg while (len != 0)
313 1.1 mrg {
314 1.1 mrg *str++ = 0;
315 1.1 mrg len--;
316 1.1 mrg }
317 1.1 mrg }
318 1.1 mrg }
319 1.1 mrg else
320 1.1 mrg {
321 1.1 mrg mp_ptr pwp, qp, rp;
322 1.1 mrg mp_size_t pwn, qn;
323 1.1 mrg mp_size_t sn;
324 1.1 mrg
325 1.1 mrg pwp = powtab->p;
326 1.1 mrg pwn = powtab->n;
327 1.1 mrg sn = powtab->shift;
328 1.1 mrg
329 1.1 mrg if (un < pwn + sn || (un == pwn + sn && mpn_cmp (up + sn, pwp, un - sn) < 0))
330 1.1 mrg {
331 1.1 mrg str = mpn_dc_get_str (str, len, up, un, powtab - 1, tmp);
332 1.1 mrg }
333 1.1 mrg else
334 1.1 mrg {
335 1.1 mrg qp = tmp; /* (un - pwn + 1) limbs for qp */
336 1.1 mrg rp = up; /* pwn limbs for rp; overwrite up area */
337 1.1 mrg
338 1.1 mrg mpn_tdiv_qr (qp, rp + sn, 0L, up + sn, un - sn, pwp, pwn);
339 1.1 mrg qn = un - sn - pwn; qn += qp[qn] != 0; /* quotient size */
340 1.1 mrg
341 1.1 mrg ASSERT (qn < pwn + sn || (qn == pwn + sn && mpn_cmp (qp + sn, pwp, pwn) < 0));
342 1.1 mrg
343 1.1 mrg if (len != 0)
344 1.1 mrg len = len - powtab->digits_in_base;
345 1.1 mrg
346 1.1 mrg str = mpn_dc_get_str (str, len, qp, qn, powtab - 1, tmp + qn);
347 1.1 mrg str = mpn_dc_get_str (str, powtab->digits_in_base, rp, pwn + sn, powtab - 1, tmp);
348 1.1 mrg }
349 1.1 mrg }
350 1.1 mrg return str;
351 1.1 mrg }
352 1.1 mrg
353 1.1 mrg
354 1.1 mrg /* There are no leading zeros on the digits generated at str, but that's not
356 1.1 mrg currently a documented feature. */
357 1.1 mrg
358 1.1 mrg size_t
359 1.1 mrg mpn_get_str (unsigned char *str, int base, mp_ptr up, mp_size_t un)
360 1.1 mrg {
361 1.1 mrg mp_ptr powtab_mem, powtab_mem_ptr;
362 1.1 mrg mp_limb_t big_base;
363 1.1 mrg size_t digits_in_base;
364 1.1 mrg powers_t powtab[GMP_LIMB_BITS];
365 1.1 mrg int pi;
366 1.1 mrg mp_size_t n;
367 1.1 mrg mp_ptr p, t;
368 1.1 mrg size_t out_len;
369 1.1 mrg mp_ptr tmp;
370 1.1 mrg TMP_DECL;
371 1.1 mrg
372 1.1 mrg /* Special case zero, as the code below doesn't handle it. */
373 1.1 mrg if (un == 0)
374 1.1 mrg {
375 1.1 mrg str[0] = 0;
376 1.1 mrg return 1;
377 1.1 mrg }
378 1.1 mrg
379 1.1 mrg if (POW2_P (base))
380 1.1 mrg {
381 1.1 mrg /* The base is a power of 2. Convert from most significant end. */
382 1.1 mrg mp_limb_t n1, n0;
383 1.1 mrg int bits_per_digit = mp_bases[base].big_base;
384 1.1 mrg int cnt;
385 1.1 mrg int bit_pos;
386 1.1 mrg mp_size_t i;
387 1.1 mrg unsigned char *s = str;
388 1.1 mrg mp_bitcnt_t bits;
389 1.1 mrg
390 1.1 mrg n1 = up[un - 1];
391 1.1 mrg count_leading_zeros (cnt, n1);
392 1.1 mrg
393 1.1 mrg /* BIT_POS should be R when input ends in least significant nibble,
394 1.1 mrg R + bits_per_digit * n when input ends in nth least significant
395 1.1 mrg nibble. */
396 1.1 mrg
397 1.1 mrg bits = (mp_bitcnt_t) GMP_NUMB_BITS * un - cnt + GMP_NAIL_BITS;
398 1.1 mrg cnt = bits % bits_per_digit;
399 1.1 mrg if (cnt != 0)
400 1.1 mrg bits += bits_per_digit - cnt;
401 1.1 mrg bit_pos = bits - (mp_bitcnt_t) (un - 1) * GMP_NUMB_BITS;
402 1.1 mrg
403 1.1 mrg /* Fast loop for bit output. */
404 1.1 mrg i = un - 1;
405 1.1 mrg for (;;)
406 1.1 mrg {
407 1.1 mrg bit_pos -= bits_per_digit;
408 1.1 mrg while (bit_pos >= 0)
409 1.1 mrg {
410 1.1 mrg *s++ = (n1 >> bit_pos) & ((1 << bits_per_digit) - 1);
411 1.1 mrg bit_pos -= bits_per_digit;
412 1.1 mrg }
413 1.1 mrg i--;
414 1.1 mrg if (i < 0)
415 1.1 mrg break;
416 1.1 mrg n0 = (n1 << -bit_pos) & ((1 << bits_per_digit) - 1);
417 1.1 mrg n1 = up[i];
418 1.1 mrg bit_pos += GMP_NUMB_BITS;
419 1.1 mrg *s++ = n0 | (n1 >> bit_pos);
420 1.1 mrg }
421 1.1 mrg
422 1.1 mrg return s - str;
423 1.1 mrg }
424 1.1 mrg
425 1.1 mrg /* General case. The base is not a power of 2. */
426 1.1 mrg
427 1.1 mrg if (BELOW_THRESHOLD (un, GET_STR_PRECOMPUTE_THRESHOLD))
428 1.1 mrg return mpn_sb_get_str (str, (size_t) 0, up, un, base) - str;
429 1.1 mrg
430 1.1 mrg TMP_MARK;
431 1.1 mrg
432 1.1 mrg /* Allocate one large block for the powers of big_base. */
433 1.1 mrg powtab_mem = TMP_BALLOC_LIMBS (mpn_dc_get_str_powtab_alloc (un));
434 1.1 mrg powtab_mem_ptr = powtab_mem;
435 1.1 mrg
436 1.1 mrg /* Compute a table of powers, were the largest power is >= sqrt(U). */
437 1.1 mrg
438 1.1 mrg big_base = mp_bases[base].big_base;
439 1.1 mrg digits_in_base = mp_bases[base].chars_per_limb;
440 1.1 mrg
441 1.1 mrg {
442 1.1 mrg mp_size_t n_pows, xn, pn, exptab[GMP_LIMB_BITS], bexp;
443 1.1 mrg mp_limb_t cy;
444 1.1 mrg mp_size_t shift;
445 1.1 mrg
446 1.1 mrg n_pows = 0;
447 1.1 mrg xn = 1 + un*(mp_bases[base].chars_per_bit_exactly*GMP_NUMB_BITS)/mp_bases[base].chars_per_limb;
448 1.1 mrg for (pn = xn; pn != 1; pn = (pn + 1) >> 1)
449 1.1 mrg {
450 1.1 mrg exptab[n_pows] = pn;
451 1.1 mrg n_pows++;
452 1.1 mrg }
453 1.1 mrg exptab[n_pows] = 1;
454 1.1 mrg
455 1.1 mrg powtab[0].p = &big_base;
456 1.1 mrg powtab[0].n = 1;
457 1.1 mrg powtab[0].digits_in_base = digits_in_base;
458 1.1 mrg powtab[0].base = base;
459 1.1 mrg powtab[0].shift = 0;
460 1.1 mrg
461 1.1 mrg powtab[1].p = powtab_mem_ptr; powtab_mem_ptr += 2;
462 1.1 mrg powtab[1].p[0] = big_base;
463 1.1 mrg powtab[1].n = 1;
464 1.1 mrg powtab[1].digits_in_base = digits_in_base;
465 1.1 mrg powtab[1].base = base;
466 1.1 mrg powtab[1].shift = 0;
467 1.1 mrg
468 1.1 mrg n = 1;
469 1.1 mrg p = &big_base;
470 1.1 mrg bexp = 1;
471 1.1 mrg shift = 0;
472 1.1 mrg for (pi = 2; pi < n_pows; pi++)
473 1.1 mrg {
474 1.1 mrg t = powtab_mem_ptr;
475 1.1 mrg powtab_mem_ptr += 2 * n + 2;
476 1.1 mrg
477 1.1 mrg ASSERT_ALWAYS (powtab_mem_ptr < powtab_mem + mpn_dc_get_str_powtab_alloc (un));
478 1.1 mrg
479 1.1 mrg mpn_sqr (t, p, n);
480 1.1 mrg
481 1.1 mrg digits_in_base *= 2;
482 1.1 mrg n *= 2; n -= t[n - 1] == 0;
483 1.1 mrg bexp *= 2;
484 1.1 mrg
485 1.1 mrg if (bexp + 1 < exptab[n_pows - pi])
486 1.1 mrg {
487 1.1 mrg digits_in_base += mp_bases[base].chars_per_limb;
488 1.1 mrg cy = mpn_mul_1 (t, t, n, big_base);
489 1.1 mrg t[n] = cy;
490 1.1 mrg n += cy != 0;
491 1.1 mrg bexp += 1;
492 1.1 mrg }
493 1.1 mrg shift *= 2;
494 1.1 mrg /* Strip low zero limbs. */
495 1.1 mrg while (t[0] == 0)
496 1.1 mrg {
497 1.1 mrg t++;
498 1.1 mrg n--;
499 1.1 mrg shift++;
500 1.1 mrg }
501 1.1 mrg p = t;
502 1.1 mrg powtab[pi].p = p;
503 1.1 mrg powtab[pi].n = n;
504 1.1 mrg powtab[pi].digits_in_base = digits_in_base;
505 1.1 mrg powtab[pi].base = base;
506 1.1 mrg powtab[pi].shift = shift;
507 1.1 mrg }
508 1.1 mrg
509 1.1 mrg for (pi = 1; pi < n_pows; pi++)
510 1.1 mrg {
511 1.1 mrg t = powtab[pi].p;
512 1.1 mrg n = powtab[pi].n;
513 1.1 mrg cy = mpn_mul_1 (t, t, n, big_base);
514 1.1 mrg t[n] = cy;
515 1.1 mrg n += cy != 0;
516 1.1 mrg if (t[0] == 0)
517 1.1 mrg {
518 1.1 mrg powtab[pi].p = t + 1;
519 1.1 mrg n--;
520 1.1 mrg powtab[pi].shift++;
521 1.1 mrg }
522 1.1 mrg powtab[pi].n = n;
523 1.1 mrg powtab[pi].digits_in_base += mp_bases[base].chars_per_limb;
524 1.1 mrg }
525 1.1 mrg
526 1.1 mrg #if 0
527 1.1 mrg { int i;
528 1.1 mrg printf ("Computed table values for base=%d, un=%d, xn=%d:\n", base, un, xn);
529 1.1 mrg for (i = 0; i < n_pows; i++)
530 1.1 mrg printf ("%2d: %10ld %10ld %11ld %ld\n", i, exptab[n_pows-i], powtab[i].n, powtab[i].digits_in_base, powtab[i].shift);
531 1.1 mrg }
532 1.1 mrg #endif
533 1.1 mrg }
534 1.1 mrg
535 1.1 mrg /* Using our precomputed powers, now in powtab[], convert our number. */
536 1.1 mrg tmp = TMP_BALLOC_LIMBS (mpn_dc_get_str_itch (un));
537 1.1 mrg out_len = mpn_dc_get_str (str, 0, up, un, powtab - 1 + pi, tmp) - str;
538 1.1 mrg TMP_FREE;
539
540 return out_len;
541 }
542