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