1 /* mpn_set_str (mp_ptr res_ptr, const char *str, size_t str_len, int base) --
2 Convert a STR_LEN long base BASE byte string pointed to by STR to a limb
3 vector pointed to by RES_PTR. Return the number of limbs in RES_PTR.
5 Contributed to the GNU project by Torbjorn Granlund.
7 THE FUNCTIONS IN THIS FILE, EXCEPT mpn_set_str, ARE INTERNAL WITH A MUTABLE
8 INTERFACE. IT IS ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN
9 FACT, IT IS ALMOST GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE
12 Copyright 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002, 2004, 2006, 2007,
13 2008 Free Software Foundation, Inc.
15 This file is part of the GNU MP Library.
17 The GNU MP Library is free software; you can redistribute it and/or modify
18 it under the terms of the GNU Lesser General Public License as published by
19 the Free Software Foundation; either version 3 of the License, or (at your
20 option) any later version.
22 The GNU MP Library is distributed in the hope that it will be useful, but
23 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
25 License for more details.
27 You should have received a copy of the GNU Lesser General Public License
28 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
33 Perhaps do not compute the highest power?
34 Instead, multiply twice by the 2nd highest power:
40 |_______________| final result
47 |___________| intermediate result
50 |_______________| final result
52 Generalizing that idea, perhaps we should make powtab contain successive
61 mpn_set_str (mp_ptr rp, const unsigned char *str, size_t str_len, int base)
65 /* The base is a power of 2. Read the input string from least to most
66 significant character/digit. */
68 const unsigned char *s;
72 int bits_per_indigit = mp_bases[base].big_base;
78 for (s = str + str_len - 1; s >= str; s--)
82 res_digit |= ((mp_limb_t) inp_digit << next_bitpos) & GMP_NUMB_MASK;
83 next_bitpos += bits_per_indigit;
84 if (next_bitpos >= GMP_NUMB_BITS)
86 rp[size++] = res_digit;
87 next_bitpos -= GMP_NUMB_BITS;
88 res_digit = inp_digit >> (bits_per_indigit - next_bitpos);
93 rp[size++] = res_digit;
97 if (BELOW_THRESHOLD (str_len, SET_STR_PRECOMPUTE_THRESHOLD))
98 return mpn_bc_set_str (rp, str, str_len, base);
101 mp_ptr powtab_mem, tp;
102 powers_t powtab[GMP_LIMB_BITS];
110 chars_per_limb = mp_bases[base].chars_per_limb;
112 un = str_len / chars_per_limb + 1;
114 /* Allocate one large block for the powers of big_base. */
115 powtab_mem = TMP_BALLOC_LIMBS (mpn_dc_set_str_powtab_alloc (un));
117 mpn_set_str_compute_powtab (powtab, powtab_mem, un, base);
119 tp = TMP_BALLOC_LIMBS (mpn_dc_set_str_itch (un));
120 size = mpn_dc_set_str (rp, str, str_len, powtab, tp);
128 mpn_set_str_compute_powtab (powers_t *powtab, mp_ptr powtab_mem, mp_size_t un, int base)
130 mp_ptr powtab_mem_ptr;
134 unsigned normalization_steps;
135 mp_limb_t big_base, big_base_inverted;
137 size_t digits_in_base;
140 powtab_mem_ptr = powtab_mem;
142 chars_per_limb = mp_bases[base].chars_per_limb;
143 big_base = mp_bases[base].big_base;
144 big_base_inverted = mp_bases[base].big_base_inverted;
145 count_leading_zeros (normalization_steps, big_base);
150 digits_in_base = chars_per_limb;
155 count_leading_zeros (i, un - 1);
156 i = GMP_LIMB_BITS - 1 - i;
160 powtab[i].digits_in_base = digits_in_base;
161 powtab[i].base = base;
165 for (pi = i - 1; pi >= 0; pi--)
168 powtab_mem_ptr += 2 * n;
170 ASSERT_ALWAYS (powtab_mem_ptr < powtab_mem + mpn_dc_set_str_powtab_alloc (un));
173 n = 2 * n - 1; n += t[n] != 0;
176 if ((((un - 1) >> pi) & 2) == 0)
178 mpn_divexact_1 (t, t, n, big_base);
180 digits_in_base -= chars_per_limb;
183 if (CLEVER_CONDITION_1 ())
185 /* perform adjustment operation of previous */
186 cy = mpn_mul_1 (p, p, n, big_base);
188 if (CLEVER_CONDITION_2 ())
190 /* perform adjustment operation of new */
191 cy = mpn_mul_1 (t, t, n, big_base);
195 /* Strip low zero limbs, but be careful to keep the result divisible by
197 while (t[0] == 0 && (t[1] & ((big_base & -big_base) - 1)) == 0)
206 powtab[pi].digits_in_base = digits_in_base;
207 powtab[pi].base = base;
208 powtab[pi].shift = shift;
213 mpn_dc_set_str (mp_ptr rp, const unsigned char *str, size_t str_len,
214 const powers_t *powtab, mp_ptr tp)
216 size_t len_lo, len_hi;
218 mp_size_t ln, hn, n, sn;
220 len_lo = powtab->digits_in_base;
222 if (str_len <= len_lo)
224 if (BELOW_THRESHOLD (str_len, SET_STR_DC_THRESHOLD))
225 return mpn_bc_set_str (rp, str, str_len, powtab->base);
227 return mpn_dc_set_str (rp, str, str_len, powtab + 1, tp);
230 len_hi = str_len - len_lo;
231 ASSERT (len_lo >= len_hi);
233 if (BELOW_THRESHOLD (len_hi, SET_STR_DC_THRESHOLD))
234 hn = mpn_bc_set_str (tp, str, len_hi, powtab->base);
236 hn = mpn_dc_set_str (tp, str, len_hi, powtab + 1, rp);
242 MPN_ZERO (rp, powtab->n + sn);
247 mpn_mul (rp + sn, powtab->p, powtab->n, tp, hn);
249 mpn_mul (rp + sn, tp, hn, powtab->p, powtab->n);
253 str = str + str_len - len_lo;
254 if (BELOW_THRESHOLD (len_lo, SET_STR_DC_THRESHOLD))
255 ln = mpn_bc_set_str (tp, str, len_lo, powtab->base);
257 ln = mpn_dc_set_str (tp, str, len_lo, powtab + 1, tp + powtab->n + sn + 1);
261 cy = mpn_add_n (rp, rp, tp, ln);
262 mpn_incr_u (rp + ln, cy);
264 n = hn + powtab->n + sn;
265 return n - (rp[n - 1] == 0);
269 mpn_bc_set_str (mp_ptr rp, const unsigned char *str, size_t str_len, int base)
281 ASSERT (base < numberof (mp_bases));
282 ASSERT (str_len >= 1);
284 big_base = mp_bases[base].big_base;
285 chars_per_limb = mp_bases[base].chars_per_limb;
288 for (i = chars_per_limb; i < str_len; i += chars_per_limb)
292 { /* This is a common case.
293 Help the compiler to avoid multiplication. */
294 for (j = MP_BASES_CHARS_PER_LIMB_10 - 1; j != 0; j--)
295 res_digit = res_digit * 10 + *str++;
299 for (j = chars_per_limb - 1; j != 0; j--)
300 res_digit = res_digit * base + *str++;
313 #if HAVE_NATIVE_mpn_mul_1c
314 cy_limb = mpn_mul_1c (rp, rp, size, big_base, res_digit);
316 cy_limb = mpn_mul_1 (rp, rp, size, big_base);
317 cy_limb += mpn_add_1 (rp, rp, size, res_digit);
320 rp[size++] = cy_limb;
327 { /* This is a common case.
328 Help the compiler to avoid multiplication. */
329 for (j = str_len - (i - MP_BASES_CHARS_PER_LIMB_10) - 1; j > 0; j--)
331 res_digit = res_digit * 10 + *str++;
337 for (j = str_len - (i - chars_per_limb) - 1; j > 0; j--)
339 res_digit = res_digit * base + *str++;
354 #if HAVE_NATIVE_mpn_mul_1c
355 cy_limb = mpn_mul_1c (rp, rp, size, big_base, res_digit);
357 cy_limb = mpn_mul_1 (rp, rp, size, big_base);
358 cy_limb += mpn_add_1 (rp, rp, size, res_digit);
361 rp[size++] = cy_limb;