xref: /dragonfly/contrib/gmp/mpn/generic/set_str.c (revision 86d7f5d3)
1*86d7f5d3SJohn Marino /* mpn_set_str (mp_ptr res_ptr, const char *str, size_t str_len, int base) --
2*86d7f5d3SJohn Marino    Convert a STR_LEN long base BASE byte string pointed to by STR to a limb
3*86d7f5d3SJohn Marino    vector pointed to by RES_PTR.  Return the number of limbs in RES_PTR.
4*86d7f5d3SJohn Marino 
5*86d7f5d3SJohn Marino    Contributed to the GNU project by Torbjorn Granlund.
6*86d7f5d3SJohn Marino 
7*86d7f5d3SJohn Marino    THE FUNCTIONS IN THIS FILE, EXCEPT mpn_set_str, ARE INTERNAL WITH A MUTABLE
8*86d7f5d3SJohn Marino    INTERFACE.  IT IS ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES.  IN
9*86d7f5d3SJohn Marino    FACT, IT IS ALMOST GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE
10*86d7f5d3SJohn Marino    GNU MP RELEASE.
11*86d7f5d3SJohn Marino 
12*86d7f5d3SJohn Marino Copyright 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002, 2004, 2006, 2007,
13*86d7f5d3SJohn Marino 2008 Free Software Foundation, Inc.
14*86d7f5d3SJohn Marino 
15*86d7f5d3SJohn Marino This file is part of the GNU MP Library.
16*86d7f5d3SJohn Marino 
17*86d7f5d3SJohn Marino The GNU MP Library is free software; you can redistribute it and/or modify
18*86d7f5d3SJohn Marino it under the terms of the GNU Lesser General Public License as published by
19*86d7f5d3SJohn Marino the Free Software Foundation; either version 3 of the License, or (at your
20*86d7f5d3SJohn Marino option) any later version.
21*86d7f5d3SJohn Marino 
22*86d7f5d3SJohn Marino The GNU MP Library is distributed in the hope that it will be useful, but
23*86d7f5d3SJohn Marino WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24*86d7f5d3SJohn Marino or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
25*86d7f5d3SJohn Marino License for more details.
26*86d7f5d3SJohn Marino 
27*86d7f5d3SJohn Marino You should have received a copy of the GNU Lesser General Public License
28*86d7f5d3SJohn Marino along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
29*86d7f5d3SJohn Marino 
30*86d7f5d3SJohn Marino 
31*86d7f5d3SJohn Marino /* TODO:
32*86d7f5d3SJohn Marino 
33*86d7f5d3SJohn Marino       Perhaps do not compute the highest power?
34*86d7f5d3SJohn Marino       Instead, multiply twice by the 2nd highest power:
35*86d7f5d3SJohn Marino 
36*86d7f5d3SJohn Marino 	       _______
37*86d7f5d3SJohn Marino 	      |_______|  hp
38*86d7f5d3SJohn Marino 	      |_______|  pow
39*86d7f5d3SJohn Marino        _______________
40*86d7f5d3SJohn Marino       |_______________|  final result
41*86d7f5d3SJohn Marino 
42*86d7f5d3SJohn Marino 
43*86d7f5d3SJohn Marino 	       _______
44*86d7f5d3SJohn Marino 	      |_______|  hp
45*86d7f5d3SJohn Marino 		  |___|  pow[-1]
46*86d7f5d3SJohn Marino 	   ___________
47*86d7f5d3SJohn Marino 	  |___________|  intermediate result
48*86d7f5d3SJohn Marino 		  |___|  pow[-1]
49*86d7f5d3SJohn Marino        _______________
50*86d7f5d3SJohn Marino       |_______________|  final result
51*86d7f5d3SJohn Marino 
52*86d7f5d3SJohn Marino       Generalizing that idea, perhaps we should make powtab contain successive
53*86d7f5d3SJohn Marino       cubes, not squares.
54*86d7f5d3SJohn Marino */
55*86d7f5d3SJohn Marino 
56*86d7f5d3SJohn Marino #include "gmp.h"
57*86d7f5d3SJohn Marino #include "gmp-impl.h"
58*86d7f5d3SJohn Marino #include "longlong.h"
59*86d7f5d3SJohn Marino 
60*86d7f5d3SJohn Marino mp_size_t
mpn_set_str(mp_ptr rp,const unsigned char * str,size_t str_len,int base)61*86d7f5d3SJohn Marino mpn_set_str (mp_ptr rp, const unsigned char *str, size_t str_len, int base)
62*86d7f5d3SJohn Marino {
63*86d7f5d3SJohn Marino   if (POW2_P (base))
64*86d7f5d3SJohn Marino     {
65*86d7f5d3SJohn Marino       /* The base is a power of 2.  Read the input string from least to most
66*86d7f5d3SJohn Marino 	 significant character/digit.  */
67*86d7f5d3SJohn Marino 
68*86d7f5d3SJohn Marino       const unsigned char *s;
69*86d7f5d3SJohn Marino       int next_bitpos;
70*86d7f5d3SJohn Marino       mp_limb_t res_digit;
71*86d7f5d3SJohn Marino       mp_size_t size;
72*86d7f5d3SJohn Marino       int bits_per_indigit = mp_bases[base].big_base;
73*86d7f5d3SJohn Marino 
74*86d7f5d3SJohn Marino       size = 0;
75*86d7f5d3SJohn Marino       res_digit = 0;
76*86d7f5d3SJohn Marino       next_bitpos = 0;
77*86d7f5d3SJohn Marino 
78*86d7f5d3SJohn Marino       for (s = str + str_len - 1; s >= str; s--)
79*86d7f5d3SJohn Marino 	{
80*86d7f5d3SJohn Marino 	  int inp_digit = *s;
81*86d7f5d3SJohn Marino 
82*86d7f5d3SJohn Marino 	  res_digit |= ((mp_limb_t) inp_digit << next_bitpos) & GMP_NUMB_MASK;
83*86d7f5d3SJohn Marino 	  next_bitpos += bits_per_indigit;
84*86d7f5d3SJohn Marino 	  if (next_bitpos >= GMP_NUMB_BITS)
85*86d7f5d3SJohn Marino 	    {
86*86d7f5d3SJohn Marino 	      rp[size++] = res_digit;
87*86d7f5d3SJohn Marino 	      next_bitpos -= GMP_NUMB_BITS;
88*86d7f5d3SJohn Marino 	      res_digit = inp_digit >> (bits_per_indigit - next_bitpos);
89*86d7f5d3SJohn Marino 	    }
90*86d7f5d3SJohn Marino 	}
91*86d7f5d3SJohn Marino 
92*86d7f5d3SJohn Marino       if (res_digit != 0)
93*86d7f5d3SJohn Marino 	rp[size++] = res_digit;
94*86d7f5d3SJohn Marino       return size;
95*86d7f5d3SJohn Marino     }
96*86d7f5d3SJohn Marino 
97*86d7f5d3SJohn Marino   if (BELOW_THRESHOLD (str_len, SET_STR_PRECOMPUTE_THRESHOLD))
98*86d7f5d3SJohn Marino     return mpn_bc_set_str (rp, str, str_len, base);
99*86d7f5d3SJohn Marino   else
100*86d7f5d3SJohn Marino     {
101*86d7f5d3SJohn Marino       mp_ptr powtab_mem, tp;
102*86d7f5d3SJohn Marino       powers_t powtab[GMP_LIMB_BITS];
103*86d7f5d3SJohn Marino       int chars_per_limb;
104*86d7f5d3SJohn Marino       mp_size_t size;
105*86d7f5d3SJohn Marino       mp_size_t un;
106*86d7f5d3SJohn Marino       TMP_DECL;
107*86d7f5d3SJohn Marino 
108*86d7f5d3SJohn Marino       TMP_MARK;
109*86d7f5d3SJohn Marino 
110*86d7f5d3SJohn Marino       chars_per_limb = mp_bases[base].chars_per_limb;
111*86d7f5d3SJohn Marino 
112*86d7f5d3SJohn Marino       un = str_len / chars_per_limb + 1;
113*86d7f5d3SJohn Marino 
114*86d7f5d3SJohn Marino       /* Allocate one large block for the powers of big_base.  */
115*86d7f5d3SJohn Marino       powtab_mem = TMP_BALLOC_LIMBS (mpn_dc_set_str_powtab_alloc (un));
116*86d7f5d3SJohn Marino 
117*86d7f5d3SJohn Marino       mpn_set_str_compute_powtab (powtab, powtab_mem, un, base);
118*86d7f5d3SJohn Marino 
119*86d7f5d3SJohn Marino       tp = TMP_BALLOC_LIMBS (mpn_dc_set_str_itch (un));
120*86d7f5d3SJohn Marino       size = mpn_dc_set_str (rp, str, str_len, powtab, tp);
121*86d7f5d3SJohn Marino 
122*86d7f5d3SJohn Marino       TMP_FREE;
123*86d7f5d3SJohn Marino       return size;
124*86d7f5d3SJohn Marino     }
125*86d7f5d3SJohn Marino }
126*86d7f5d3SJohn Marino 
127*86d7f5d3SJohn Marino void
mpn_set_str_compute_powtab(powers_t * powtab,mp_ptr powtab_mem,mp_size_t un,int base)128*86d7f5d3SJohn Marino mpn_set_str_compute_powtab (powers_t *powtab, mp_ptr powtab_mem, mp_size_t un, int base)
129*86d7f5d3SJohn Marino {
130*86d7f5d3SJohn Marino   mp_ptr powtab_mem_ptr;
131*86d7f5d3SJohn Marino   long i, pi;
132*86d7f5d3SJohn Marino   mp_size_t n;
133*86d7f5d3SJohn Marino   mp_ptr p, t;
134*86d7f5d3SJohn Marino   unsigned normalization_steps;
135*86d7f5d3SJohn Marino   mp_limb_t big_base, big_base_inverted;
136*86d7f5d3SJohn Marino   int chars_per_limb;
137*86d7f5d3SJohn Marino   size_t digits_in_base;
138*86d7f5d3SJohn Marino   mp_size_t shift;
139*86d7f5d3SJohn Marino 
140*86d7f5d3SJohn Marino   powtab_mem_ptr = powtab_mem;
141*86d7f5d3SJohn Marino 
142*86d7f5d3SJohn Marino   chars_per_limb = mp_bases[base].chars_per_limb;
143*86d7f5d3SJohn Marino   big_base = mp_bases[base].big_base;
144*86d7f5d3SJohn Marino   big_base_inverted = mp_bases[base].big_base_inverted;
145*86d7f5d3SJohn Marino   count_leading_zeros (normalization_steps, big_base);
146*86d7f5d3SJohn Marino 
147*86d7f5d3SJohn Marino   p = powtab_mem_ptr;
148*86d7f5d3SJohn Marino   powtab_mem_ptr += 1;
149*86d7f5d3SJohn Marino 
150*86d7f5d3SJohn Marino   digits_in_base = chars_per_limb;
151*86d7f5d3SJohn Marino 
152*86d7f5d3SJohn Marino   p[0] = big_base;
153*86d7f5d3SJohn Marino   n = 1;
154*86d7f5d3SJohn Marino 
155*86d7f5d3SJohn Marino   count_leading_zeros (i, un - 1);
156*86d7f5d3SJohn Marino   i = GMP_LIMB_BITS - 1 - i;
157*86d7f5d3SJohn Marino 
158*86d7f5d3SJohn Marino   powtab[i].p = p;
159*86d7f5d3SJohn Marino   powtab[i].n = n;
160*86d7f5d3SJohn Marino   powtab[i].digits_in_base = digits_in_base;
161*86d7f5d3SJohn Marino   powtab[i].base = base;
162*86d7f5d3SJohn Marino   powtab[i].shift = 0;
163*86d7f5d3SJohn Marino 
164*86d7f5d3SJohn Marino   shift = 0;
165*86d7f5d3SJohn Marino   for (pi = i - 1; pi >= 0; pi--)
166*86d7f5d3SJohn Marino     {
167*86d7f5d3SJohn Marino       t = powtab_mem_ptr;
168*86d7f5d3SJohn Marino       powtab_mem_ptr += 2 * n;
169*86d7f5d3SJohn Marino 
170*86d7f5d3SJohn Marino       ASSERT_ALWAYS (powtab_mem_ptr < powtab_mem + mpn_dc_set_str_powtab_alloc (un));
171*86d7f5d3SJohn Marino 
172*86d7f5d3SJohn Marino       mpn_sqr (t, p, n);
173*86d7f5d3SJohn Marino       n = 2 * n - 1; n += t[n] != 0;
174*86d7f5d3SJohn Marino       digits_in_base *= 2;
175*86d7f5d3SJohn Marino #if 1
176*86d7f5d3SJohn Marino       if ((((un - 1) >> pi) & 2) == 0)
177*86d7f5d3SJohn Marino 	{
178*86d7f5d3SJohn Marino 	  mpn_divexact_1 (t, t, n, big_base);
179*86d7f5d3SJohn Marino 	  n -= t[n - 1] == 0;
180*86d7f5d3SJohn Marino 	  digits_in_base -= chars_per_limb;
181*86d7f5d3SJohn Marino 	}
182*86d7f5d3SJohn Marino #else
183*86d7f5d3SJohn Marino       if (CLEVER_CONDITION_1 ())
184*86d7f5d3SJohn Marino 	{
185*86d7f5d3SJohn Marino 	  /* perform adjustment operation of previous */
186*86d7f5d3SJohn Marino 	  cy = mpn_mul_1 (p, p, n, big_base);
187*86d7f5d3SJohn Marino 	}
188*86d7f5d3SJohn Marino       if (CLEVER_CONDITION_2 ())
189*86d7f5d3SJohn Marino 	{
190*86d7f5d3SJohn Marino 	  /* perform adjustment operation of new */
191*86d7f5d3SJohn Marino 	  cy = mpn_mul_1 (t, t, n, big_base);
192*86d7f5d3SJohn Marino 	}
193*86d7f5d3SJohn Marino #endif
194*86d7f5d3SJohn Marino       shift *= 2;
195*86d7f5d3SJohn Marino       /* Strip low zero limbs, but be careful to keep the result divisible by
196*86d7f5d3SJohn Marino 	 big_base.  */
197*86d7f5d3SJohn Marino       while (t[0] == 0 && (t[1] & ((big_base & -big_base) - 1)) == 0)
198*86d7f5d3SJohn Marino 	{
199*86d7f5d3SJohn Marino 	  t++;
200*86d7f5d3SJohn Marino 	  n--;
201*86d7f5d3SJohn Marino 	  shift++;
202*86d7f5d3SJohn Marino 	}
203*86d7f5d3SJohn Marino       p = t;
204*86d7f5d3SJohn Marino       powtab[pi].p = p;
205*86d7f5d3SJohn Marino       powtab[pi].n = n;
206*86d7f5d3SJohn Marino       powtab[pi].digits_in_base = digits_in_base;
207*86d7f5d3SJohn Marino       powtab[pi].base = base;
208*86d7f5d3SJohn Marino       powtab[pi].shift = shift;
209*86d7f5d3SJohn Marino     }
210*86d7f5d3SJohn Marino }
211*86d7f5d3SJohn Marino 
212*86d7f5d3SJohn Marino mp_size_t
mpn_dc_set_str(mp_ptr rp,const unsigned char * str,size_t str_len,const powers_t * powtab,mp_ptr tp)213*86d7f5d3SJohn Marino mpn_dc_set_str (mp_ptr rp, const unsigned char *str, size_t str_len,
214*86d7f5d3SJohn Marino 		const powers_t *powtab, mp_ptr tp)
215*86d7f5d3SJohn Marino {
216*86d7f5d3SJohn Marino   size_t len_lo, len_hi;
217*86d7f5d3SJohn Marino   mp_limb_t cy;
218*86d7f5d3SJohn Marino   mp_size_t ln, hn, n, sn;
219*86d7f5d3SJohn Marino 
220*86d7f5d3SJohn Marino   len_lo = powtab->digits_in_base;
221*86d7f5d3SJohn Marino 
222*86d7f5d3SJohn Marino   if (str_len <= len_lo)
223*86d7f5d3SJohn Marino     {
224*86d7f5d3SJohn Marino       if (BELOW_THRESHOLD (str_len, SET_STR_DC_THRESHOLD))
225*86d7f5d3SJohn Marino 	return mpn_bc_set_str (rp, str, str_len, powtab->base);
226*86d7f5d3SJohn Marino       else
227*86d7f5d3SJohn Marino 	return mpn_dc_set_str (rp, str, str_len, powtab + 1, tp);
228*86d7f5d3SJohn Marino     }
229*86d7f5d3SJohn Marino 
230*86d7f5d3SJohn Marino   len_hi = str_len - len_lo;
231*86d7f5d3SJohn Marino   ASSERT (len_lo >= len_hi);
232*86d7f5d3SJohn Marino 
233*86d7f5d3SJohn Marino   if (BELOW_THRESHOLD (len_hi, SET_STR_DC_THRESHOLD))
234*86d7f5d3SJohn Marino     hn = mpn_bc_set_str (tp, str, len_hi, powtab->base);
235*86d7f5d3SJohn Marino   else
236*86d7f5d3SJohn Marino     hn = mpn_dc_set_str (tp, str, len_hi, powtab + 1, rp);
237*86d7f5d3SJohn Marino 
238*86d7f5d3SJohn Marino   sn = powtab->shift;
239*86d7f5d3SJohn Marino 
240*86d7f5d3SJohn Marino   if (hn == 0)
241*86d7f5d3SJohn Marino     {
242*86d7f5d3SJohn Marino       MPN_ZERO (rp, powtab->n + sn);
243*86d7f5d3SJohn Marino     }
244*86d7f5d3SJohn Marino   else
245*86d7f5d3SJohn Marino     {
246*86d7f5d3SJohn Marino       if (powtab->n > hn)
247*86d7f5d3SJohn Marino 	mpn_mul (rp + sn, powtab->p, powtab->n, tp, hn);
248*86d7f5d3SJohn Marino       else
249*86d7f5d3SJohn Marino 	mpn_mul (rp + sn, tp, hn, powtab->p, powtab->n);
250*86d7f5d3SJohn Marino       MPN_ZERO (rp, sn);
251*86d7f5d3SJohn Marino     }
252*86d7f5d3SJohn Marino 
253*86d7f5d3SJohn Marino   str = str + str_len - len_lo;
254*86d7f5d3SJohn Marino   if (BELOW_THRESHOLD (len_lo, SET_STR_DC_THRESHOLD))
255*86d7f5d3SJohn Marino     ln = mpn_bc_set_str (tp, str, len_lo, powtab->base);
256*86d7f5d3SJohn Marino   else
257*86d7f5d3SJohn Marino     ln = mpn_dc_set_str (tp, str, len_lo, powtab + 1, tp + powtab->n + sn + 1);
258*86d7f5d3SJohn Marino 
259*86d7f5d3SJohn Marino   if (ln != 0)
260*86d7f5d3SJohn Marino     {
261*86d7f5d3SJohn Marino       cy = mpn_add_n (rp, rp, tp, ln);
262*86d7f5d3SJohn Marino       mpn_incr_u (rp + ln, cy);
263*86d7f5d3SJohn Marino     }
264*86d7f5d3SJohn Marino   n = hn + powtab->n + sn;
265*86d7f5d3SJohn Marino   return n - (rp[n - 1] == 0);
266*86d7f5d3SJohn Marino }
267*86d7f5d3SJohn Marino 
268*86d7f5d3SJohn Marino mp_size_t
mpn_bc_set_str(mp_ptr rp,const unsigned char * str,size_t str_len,int base)269*86d7f5d3SJohn Marino mpn_bc_set_str (mp_ptr rp, const unsigned char *str, size_t str_len, int base)
270*86d7f5d3SJohn Marino {
271*86d7f5d3SJohn Marino   mp_size_t size;
272*86d7f5d3SJohn Marino   size_t i;
273*86d7f5d3SJohn Marino   long j;
274*86d7f5d3SJohn Marino   mp_limb_t cy_limb;
275*86d7f5d3SJohn Marino 
276*86d7f5d3SJohn Marino   mp_limb_t big_base;
277*86d7f5d3SJohn Marino   int chars_per_limb;
278*86d7f5d3SJohn Marino   mp_limb_t res_digit;
279*86d7f5d3SJohn Marino 
280*86d7f5d3SJohn Marino   ASSERT (base >= 2);
281*86d7f5d3SJohn Marino   ASSERT (base < numberof (mp_bases));
282*86d7f5d3SJohn Marino   ASSERT (str_len >= 1);
283*86d7f5d3SJohn Marino 
284*86d7f5d3SJohn Marino   big_base = mp_bases[base].big_base;
285*86d7f5d3SJohn Marino   chars_per_limb = mp_bases[base].chars_per_limb;
286*86d7f5d3SJohn Marino 
287*86d7f5d3SJohn Marino   size = 0;
288*86d7f5d3SJohn Marino   for (i = chars_per_limb; i < str_len; i += chars_per_limb)
289*86d7f5d3SJohn Marino     {
290*86d7f5d3SJohn Marino       res_digit = *str++;
291*86d7f5d3SJohn Marino       if (base == 10)
292*86d7f5d3SJohn Marino 	{ /* This is a common case.
293*86d7f5d3SJohn Marino 	     Help the compiler to avoid multiplication.  */
294*86d7f5d3SJohn Marino 	  for (j = MP_BASES_CHARS_PER_LIMB_10 - 1; j != 0; j--)
295*86d7f5d3SJohn Marino 	    res_digit = res_digit * 10 + *str++;
296*86d7f5d3SJohn Marino 	}
297*86d7f5d3SJohn Marino       else
298*86d7f5d3SJohn Marino 	{
299*86d7f5d3SJohn Marino 	  for (j = chars_per_limb - 1; j != 0; j--)
300*86d7f5d3SJohn Marino 	    res_digit = res_digit * base + *str++;
301*86d7f5d3SJohn Marino 	}
302*86d7f5d3SJohn Marino 
303*86d7f5d3SJohn Marino       if (size == 0)
304*86d7f5d3SJohn Marino 	{
305*86d7f5d3SJohn Marino 	  if (res_digit != 0)
306*86d7f5d3SJohn Marino 	    {
307*86d7f5d3SJohn Marino 	      rp[0] = res_digit;
308*86d7f5d3SJohn Marino 	      size = 1;
309*86d7f5d3SJohn Marino 	    }
310*86d7f5d3SJohn Marino 	}
311*86d7f5d3SJohn Marino       else
312*86d7f5d3SJohn Marino 	{
313*86d7f5d3SJohn Marino #if HAVE_NATIVE_mpn_mul_1c
314*86d7f5d3SJohn Marino 	  cy_limb = mpn_mul_1c (rp, rp, size, big_base, res_digit);
315*86d7f5d3SJohn Marino #else
316*86d7f5d3SJohn Marino 	  cy_limb = mpn_mul_1 (rp, rp, size, big_base);
317*86d7f5d3SJohn Marino 	  cy_limb += mpn_add_1 (rp, rp, size, res_digit);
318*86d7f5d3SJohn Marino #endif
319*86d7f5d3SJohn Marino 	  if (cy_limb != 0)
320*86d7f5d3SJohn Marino 	    rp[size++] = cy_limb;
321*86d7f5d3SJohn Marino 	}
322*86d7f5d3SJohn Marino     }
323*86d7f5d3SJohn Marino 
324*86d7f5d3SJohn Marino   big_base = base;
325*86d7f5d3SJohn Marino   res_digit = *str++;
326*86d7f5d3SJohn Marino   if (base == 10)
327*86d7f5d3SJohn Marino     { /* This is a common case.
328*86d7f5d3SJohn Marino 	 Help the compiler to avoid multiplication.  */
329*86d7f5d3SJohn Marino       for (j = str_len - (i - MP_BASES_CHARS_PER_LIMB_10) - 1; j > 0; j--)
330*86d7f5d3SJohn Marino 	{
331*86d7f5d3SJohn Marino 	  res_digit = res_digit * 10 + *str++;
332*86d7f5d3SJohn Marino 	  big_base *= 10;
333*86d7f5d3SJohn Marino 	}
334*86d7f5d3SJohn Marino     }
335*86d7f5d3SJohn Marino   else
336*86d7f5d3SJohn Marino     {
337*86d7f5d3SJohn Marino       for (j = str_len - (i - chars_per_limb) - 1; j > 0; j--)
338*86d7f5d3SJohn Marino 	{
339*86d7f5d3SJohn Marino 	  res_digit = res_digit * base + *str++;
340*86d7f5d3SJohn Marino 	  big_base *= base;
341*86d7f5d3SJohn Marino 	}
342*86d7f5d3SJohn Marino     }
343*86d7f5d3SJohn Marino 
344*86d7f5d3SJohn Marino   if (size == 0)
345*86d7f5d3SJohn Marino     {
346*86d7f5d3SJohn Marino       if (res_digit != 0)
347*86d7f5d3SJohn Marino 	{
348*86d7f5d3SJohn Marino 	  rp[0] = res_digit;
349*86d7f5d3SJohn Marino 	  size = 1;
350*86d7f5d3SJohn Marino 	}
351*86d7f5d3SJohn Marino     }
352*86d7f5d3SJohn Marino   else
353*86d7f5d3SJohn Marino     {
354*86d7f5d3SJohn Marino #if HAVE_NATIVE_mpn_mul_1c
355*86d7f5d3SJohn Marino       cy_limb = mpn_mul_1c (rp, rp, size, big_base, res_digit);
356*86d7f5d3SJohn Marino #else
357*86d7f5d3SJohn Marino       cy_limb = mpn_mul_1 (rp, rp, size, big_base);
358*86d7f5d3SJohn Marino       cy_limb += mpn_add_1 (rp, rp, size, res_digit);
359*86d7f5d3SJohn Marino #endif
360*86d7f5d3SJohn Marino       if (cy_limb != 0)
361*86d7f5d3SJohn Marino 	rp[size++] = cy_limb;
362*86d7f5d3SJohn Marino     }
363*86d7f5d3SJohn Marino   return size;
364*86d7f5d3SJohn Marino }
365