00001 #include "multiprec.h"
00002 #include <string.h>
00003 #include <math.h>
00004
00005
00031 inline void
00032 ymp_assign_string(mp_ref_t self,
00033 const char *psz, char **endptr, unsigned radix)
00034 {
00035 if (radix > 36)
00036 ymp_error("文字列からの変換の基数が大きすぎる: %u", radix);
00037
00038 switch (*psz)
00039 {
00040 case '-':
00041 ++psz;
00042 self->sign = negative_sign;
00043 break;
00044 case '+':
00045 ++psz;
00046 default:
00047 self->sign = positive_sign;
00048 }
00049
00050 if (radix == 0)
00051 {
00052 if (*psz != '0') radix = 10;
00053 else switch (*++psz)
00054 {
00055 case 'B': case 'b': radix = 2; ++psz; break;
00056 case 'Q': case 'q': radix = 4; ++psz; break;
00057 case 'O': case 'o': radix = 8; ++psz; break;
00058 case 'D': case 'd': radix = 10; ++psz; break;
00059 case 'X': case 'x': radix = 16; ++psz; break;
00060 default: radix = 8; break;
00061 }
00062 }
00063
00064 ymp_reserve(self, ceil(strlen(psz)*(log(radix)/log(MULTIPREC_RADIX)))+1);
00065
00066 self->used = 0; self->digits[0] = 0;
00067 for ( ; *psz; ++psz)
00068 {
00069 digit_t c;
00070 switch (*psz)
00071 {
00072 case '0': c = 0; break; case '1': c = 1; break;
00073 case '2': c = 2; break; case '3': c = 3; break;
00074 case '4': c = 4; break; case '5': c = 5; break;
00075 case '6': c = 6; break; case '7': c = 7; break;
00076 case '8': c = 8; break; case '9': c = 9; break;
00077 case 'A': case 'a': c = 10; break;
00078 case 'B': case 'b': c = 11; break;
00079 case 'C': case 'c': c = 12; break;
00080 case 'D': case 'd': c = 13; break;
00081 case 'E': case 'e': c = 14; break;
00082 case 'F': case 'f': c = 15; break;
00083 case 'G': case 'g': c = 16; break;
00084 case 'H': case 'h': c = 17; break;
00085 case 'I': case 'i': c = 18; break;
00086 case 'J': case 'j': c = 19; break;
00087 case 'K': case 'k': c = 20; break;
00088 case 'L': case 'l': c = 21; break;
00089 case 'M': case 'm': c = 22; break;
00090 case 'N': case 'n': c = 23; break;
00091 case 'O': case 'o': c = 24; break;
00092 case 'P': case 'p': c = 25; break;
00093 case 'Q': case 'q': c = 26; break;
00094 case 'R': case 'r': c = 27; break;
00095 case 'S': case 's': c = 28; break;
00096 case 'T': case 't': c = 29; break;
00097 case 'U': case 'u': c = 30; break;
00098 case 'V': case 'v': c = 31; break;
00099 case 'W': case 'w': c = 32; break;
00100 case 'X': case 'x': c = 33; break;
00101 case 'Y': case 'y': c = 34; break;
00102 case 'Z': case 'z': c = 35; break;
00103
00104 case '_': continue;
00105 default: c = 127;
00106 }
00107 if (c >= radix) break;
00108
00109 ymp_reserve(self, self->used+1);
00110 self->used
00111 = ymp_mulabs_digit(self->digits, self->digits, radix, self->used);
00112 self->used
00113 = ymp_addabs(self->digits, self->digits, &c, self->used, 1);
00114 }
00115
00116 if (endptr) *endptr = (char*)psz;
00117 }
00118
00140 void
00141 ymp_initialize_by_string(mp_ref_t self,
00142 const char *psz, char **endptr, unsigned radix)
00143 {
00144 ymp_initialize(self);
00145 ymp_assign_string(self, psz, endptr, radix);
00146 }
00147
00148