Annotation of OpenXM_contrib/gmp/mpn/generic/set_str.c, Revision 1.1.1.2
1.1 maekawa 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
3: limb vector pointed to by RES_PTR. Return the number of limbs in
4: RES_PTR.
5:
1.1.1.2 ! maekawa 6: Copyright (C) 1991, 1992, 1993, 1994, 1996, 2000 Free Software Foundation,
! 7: Inc.
1.1 maekawa 8:
9: This file is part of the GNU MP Library.
10:
11: The GNU MP Library is free software; you can redistribute it and/or modify
1.1.1.2 ! maekawa 12: it under the terms of the GNU Lesser General Public License as published by
! 13: the Free Software Foundation; either version 2.1 of the License, or (at your
1.1 maekawa 14: option) any later version.
15:
16: The GNU MP Library is distributed in the hope that it will be useful, but
17: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1.1.1.2 ! maekawa 18: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
1.1 maekawa 19: License for more details.
20:
1.1.1.2 ! maekawa 21: You should have received a copy of the GNU Lesser General Public License
1.1 maekawa 22: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
23: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24: MA 02111-1307, USA. */
25:
26: #include "gmp.h"
27: #include "gmp-impl.h"
28:
29: mp_size_t
1.1.1.2 ! maekawa 30: #if __STDC__
! 31: mpn_set_str (mp_ptr xp, const unsigned char *str, size_t str_len, int base)
! 32: #else
1.1 maekawa 33: mpn_set_str (xp, str, str_len, base)
34: mp_ptr xp;
35: const unsigned char *str;
36: size_t str_len;
37: int base;
1.1.1.2 ! maekawa 38: #endif
1.1 maekawa 39: {
40: mp_size_t size;
41: mp_limb_t big_base;
42: int indigits_per_limb;
43: mp_limb_t res_digit;
44:
45: big_base = __mp_bases[base].big_base;
46: indigits_per_limb = __mp_bases[base].chars_per_limb;
47:
48: /* size = str_len / indigits_per_limb + 1; */
49:
50: size = 0;
51:
52: if ((base & (base - 1)) == 0)
53: {
54: /* The base is a power of 2. Read the input string from
55: least to most significant character/digit. */
56:
57: const unsigned char *s;
58: int next_bitpos;
59: int bits_per_indigit = big_base;
60:
61: res_digit = 0;
62: next_bitpos = 0;
63:
64: for (s = str + str_len - 1; s >= str; s--)
65: {
66: int inp_digit = *s;
67:
68: res_digit |= (mp_limb_t) inp_digit << next_bitpos;
69: next_bitpos += bits_per_indigit;
70: if (next_bitpos >= BITS_PER_MP_LIMB)
71: {
72: xp[size++] = res_digit;
73: next_bitpos -= BITS_PER_MP_LIMB;
74: res_digit = inp_digit >> (bits_per_indigit - next_bitpos);
75: }
76: }
77:
78: if (res_digit != 0)
79: xp[size++] = res_digit;
80: }
81: else
82: {
83: /* General case. The base is not a power of 2. */
84:
85: size_t i;
86: int j;
87: mp_limb_t cy_limb;
88:
89: for (i = indigits_per_limb; i < str_len; i += indigits_per_limb)
90: {
91: res_digit = *str++;
92: if (base == 10)
93: { /* This is a common case.
94: Help the compiler to avoid multiplication. */
95: for (j = 1; j < indigits_per_limb; j++)
96: res_digit = res_digit * 10 + *str++;
97: }
98: else
99: {
100: for (j = 1; j < indigits_per_limb; j++)
101: res_digit = res_digit * base + *str++;
102: }
103:
104: if (size == 0)
105: {
106: if (res_digit != 0)
107: {
108: xp[0] = res_digit;
109: size = 1;
110: }
111: }
112: else
113: {
114: cy_limb = mpn_mul_1 (xp, xp, size, big_base);
115: cy_limb += mpn_add_1 (xp, xp, size, res_digit);
116: if (cy_limb != 0)
117: xp[size++] = cy_limb;
118: }
119: }
120:
121: big_base = base;
122: res_digit = *str++;
123: if (base == 10)
124: { /* This is a common case.
125: Help the compiler to avoid multiplication. */
126: for (j = 1; j < str_len - (i - indigits_per_limb); j++)
127: {
128: res_digit = res_digit * 10 + *str++;
129: big_base *= 10;
130: }
131: }
132: else
133: {
134: for (j = 1; j < str_len - (i - indigits_per_limb); j++)
135: {
136: res_digit = res_digit * base + *str++;
137: big_base *= base;
138: }
139: }
140:
141: if (size == 0)
142: {
143: if (res_digit != 0)
144: {
145: xp[0] = res_digit;
146: size = 1;
147: }
148: }
149: else
150: {
151: cy_limb = mpn_mul_1 (xp, xp, size, big_base);
152: cy_limb += mpn_add_1 (xp, xp, size, res_digit);
153: if (cy_limb != 0)
154: xp[size++] = cy_limb;
155: }
156: }
157:
158: return size;
159: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>