1 /* _mpz_set_str(mp_dest, string, base) -- Convert the \0-terminated
2 string STRING in base BASE to multiple precision integer in
3 MP_DEST. Allow white space in the string. If BASE == 0 determine
4 the base in the C standard way, i.e. 0xhh...h means base 16,
5 0oo...o means base 8, otherwise assume base 10.
7 Copyright (C) 1991 Free Software Foundation, Inc.
9 This file is part of the GNU MP Library.
11 The GNU MP Library is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 The GNU MP Library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with the GNU MP Library; see the file COPYING. If not, write to
23 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
36 static signed char ascii_to_num[256] =
38 EOF,XX, XX, XX, XX, XX, XX, XX, XX, SPC,SPC,XX, XX, XX, XX, XX,
39 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
40 SPC,XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
41 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, XX, XX, XX, XX, XX, XX,
42 XX, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
43 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, XX, XX, XX, XX, XX,
44 XX, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
45 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, XX, XX, XX, XX, XX,
46 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
47 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
48 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
49 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
50 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
51 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
52 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
53 XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX
58 _mpz_set_str (MP_INT *x, const char *str, int base)
60 _mpz_set_str (x, str, base)
69 int indigits_per_limb;
87 if (str[1] == 'x' || str[1] == 'X')
96 big_base = __mp_bases[base].big_base;
97 indigits_per_limb = __mp_bases[base].chars_per_limb;
99 str_len = strlen (str);
101 size = str_len / indigits_per_limb + 1;
103 _mpz_realloc (x, size);
108 if ((base & (base - 1)) == 0)
110 /* The base is a power of 2. Read the input string from
111 least to most significant character/digit. */
115 int bits_per_indigit = big_base;
117 /* Accept and ignore 0x or 0X before hexadecimal numbers. */
118 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
127 for (s = str + str_len - 1; s >= str; s--)
130 inp_digit = ascii_to_num[inp_rawchar];
132 if (inp_digit >= base)
134 /* Was it white space? Just ignore it. */
135 if ((char) inp_digit == (char) SPC)
138 /* We found rubbish in the string. Return -1 to indicate
143 res_digit |= inp_digit << next_bitpos;
144 next_bitpos += bits_per_indigit;
145 if (next_bitpos >= BITS_PER_MP_LIMB)
147 xp[size] = res_digit;
149 next_bitpos -= BITS_PER_MP_LIMB;
150 res_digit = inp_digit >> (bits_per_indigit - next_bitpos);
154 xp[size] = res_digit;
156 for (i = size - 1; i >= 0; i--)
165 /* General case. The base is not a power of 2. */
174 for (j = 0; j < indigits_per_limb; )
176 inp_rawchar = (unsigned char) *str++;
177 inp_digit = ascii_to_num[inp_rawchar];
179 /* Negative means that the character was not a proper digit. */
180 if (inp_digit >= base)
182 /* Was it white space? Just ignore it. */
183 if ((char) inp_digit == (char) SPC)
189 res_digit = res_digit * base + inp_digit;
191 /* Increment the loop counter here, since it mustn't be
192 incremented when we do "continue" above. */
198 /* Insert RES_DIGIT into the result multi prec integer. */
199 for (i = 0; i < size; i++)
202 umul_ppmm (p1, p0, big_base, xp[i]);
215 /* We probably have some digits in RES_DIGIT (J tells how many). */
216 if ((char) inp_digit != (char) EOF)
222 /* J contains number of digits (in base BASE) remaining in
236 /* Insert ultimate RES_DIGIT into the result multi prec integer. */
237 for (i = 0; i < size; i++)
240 umul_ppmm (p1, p0, big_base, xp[i]);