Blame


1 85231fd8 2006-05-21 devnull /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
2 91c13e54 2004-02-29 devnull #include <stdlib.h>
3 91c13e54 2004-02-29 devnull #include <math.h>
4 91c13e54 2004-02-29 devnull #include <ctype.h>
5 91c13e54 2004-02-29 devnull #include <stdlib.h>
6 91c13e54 2004-02-29 devnull #include <string.h>
7 91c13e54 2004-02-29 devnull #include <errno.h>
8 e5aa96ac 2004-12-26 devnull #include "plan9.h"
9 91c13e54 2004-02-29 devnull #include "fmt.h"
10 e5aa96ac 2004-12-26 devnull #include "fmtdef.h"
11 91c13e54 2004-02-29 devnull
12 91c13e54 2004-02-29 devnull static ulong
13 91c13e54 2004-02-29 devnull umuldiv(ulong a, ulong b, ulong c)
14 91c13e54 2004-02-29 devnull {
15 91c13e54 2004-02-29 devnull double d;
16 91c13e54 2004-02-29 devnull
17 91c13e54 2004-02-29 devnull d = ((double)a * (double)b) / (double)c;
18 91c13e54 2004-02-29 devnull if(d >= 4294967295.)
19 91c13e54 2004-02-29 devnull d = 4294967295.;
20 91c13e54 2004-02-29 devnull return (ulong)d;
21 91c13e54 2004-02-29 devnull }
22 91c13e54 2004-02-29 devnull
23 91c13e54 2004-02-29 devnull /*
24 91c13e54 2004-02-29 devnull * This routine will convert to arbitrary precision
25 91c13e54 2004-02-29 devnull * floating point entirely in multi-precision fixed.
26 91c13e54 2004-02-29 devnull * The answer is the closest floating point number to
27 91c13e54 2004-02-29 devnull * the given decimal number. Exactly half way are
28 91c13e54 2004-02-29 devnull * rounded ala ieee rules.
29 91c13e54 2004-02-29 devnull * Method is to scale input decimal between .500 and .999...
30 91c13e54 2004-02-29 devnull * with external power of 2, then binary search for the
31 91c13e54 2004-02-29 devnull * closest mantissa to this decimal number.
32 91c13e54 2004-02-29 devnull * Nmant is is the required precision. (53 for ieee dp)
33 91c13e54 2004-02-29 devnull * Nbits is the max number of bits/word. (must be <= 28)
34 91c13e54 2004-02-29 devnull * Prec is calculated - the number of words of fixed mantissa.
35 91c13e54 2004-02-29 devnull */
36 91c13e54 2004-02-29 devnull enum
37 91c13e54 2004-02-29 devnull {
38 91c13e54 2004-02-29 devnull Nbits = 28, /* bits safely represented in a ulong */
39 91c13e54 2004-02-29 devnull Nmant = 53, /* bits of precision required */
40 91c13e54 2004-02-29 devnull Prec = (Nmant+Nbits+1)/Nbits, /* words of Nbits each to represent mantissa */
41 91c13e54 2004-02-29 devnull Sigbit = 1<<(Prec*Nbits-Nmant), /* first significant bit of Prec-th word */
42 91c13e54 2004-02-29 devnull Ndig = 1500,
43 91c13e54 2004-02-29 devnull One = (ulong)(1<<Nbits),
44 91c13e54 2004-02-29 devnull Half = (ulong)(One>>1),
45 91c13e54 2004-02-29 devnull Maxe = 310,
46 91c13e54 2004-02-29 devnull
47 91c13e54 2004-02-29 devnull Fsign = 1<<0, /* found - */
48 91c13e54 2004-02-29 devnull Fesign = 1<<1, /* found e- */
49 91c13e54 2004-02-29 devnull Fdpoint = 1<<2, /* found . */
50 91c13e54 2004-02-29 devnull
51 91c13e54 2004-02-29 devnull S0 = 0, /* _ _S0 +S1 #S2 .S3 */
52 91c13e54 2004-02-29 devnull S1, /* _+ #S2 .S3 */
53 91c13e54 2004-02-29 devnull S2, /* _+# #S2 .S4 eS5 */
54 91c13e54 2004-02-29 devnull S3, /* _+. #S4 */
55 91c13e54 2004-02-29 devnull S4, /* _+#.# #S4 eS5 */
56 91c13e54 2004-02-29 devnull S5, /* _+#.#e +S6 #S7 */
57 91c13e54 2004-02-29 devnull S6, /* _+#.#e+ #S7 */
58 cbeb0b26 2006-04-01 devnull S7 /* _+#.#e+# #S7 */
59 91c13e54 2004-02-29 devnull };
60 91c13e54 2004-02-29 devnull
61 91c13e54 2004-02-29 devnull static int xcmp(char*, char*);
62 91c13e54 2004-02-29 devnull static int fpcmp(char*, ulong*);
63 91c13e54 2004-02-29 devnull static void frnorm(ulong*);
64 91c13e54 2004-02-29 devnull static void divascii(char*, int*, int*, int*);
65 91c13e54 2004-02-29 devnull static void mulascii(char*, int*, int*, int*);
66 91c13e54 2004-02-29 devnull
67 91c13e54 2004-02-29 devnull typedef struct Tab Tab;
68 91c13e54 2004-02-29 devnull struct Tab
69 91c13e54 2004-02-29 devnull {
70 91c13e54 2004-02-29 devnull int bp;
71 91c13e54 2004-02-29 devnull int siz;
72 91c13e54 2004-02-29 devnull char* cmp;
73 91c13e54 2004-02-29 devnull };
74 91c13e54 2004-02-29 devnull
75 91c13e54 2004-02-29 devnull double
76 91c13e54 2004-02-29 devnull fmtstrtod(const char *as, char **aas)
77 91c13e54 2004-02-29 devnull {
78 91c13e54 2004-02-29 devnull int na, ex, dp, bp, c, i, flag, state;
79 91c13e54 2004-02-29 devnull ulong low[Prec], hig[Prec], mid[Prec];
80 91c13e54 2004-02-29 devnull double d;
81 91c13e54 2004-02-29 devnull char *s, a[Ndig];
82 91c13e54 2004-02-29 devnull
83 91c13e54 2004-02-29 devnull flag = 0; /* Fsign, Fesign, Fdpoint */
84 91c13e54 2004-02-29 devnull na = 0; /* number of digits of a[] */
85 91c13e54 2004-02-29 devnull dp = 0; /* na of decimal point */
86 91c13e54 2004-02-29 devnull ex = 0; /* exonent */
87 91c13e54 2004-02-29 devnull
88 91c13e54 2004-02-29 devnull state = S0;
89 91c13e54 2004-02-29 devnull for(s=(char*)as;; s++) {
90 91c13e54 2004-02-29 devnull c = *s;
91 91c13e54 2004-02-29 devnull if(c >= '0' && c <= '9') {
92 91c13e54 2004-02-29 devnull switch(state) {
93 91c13e54 2004-02-29 devnull case S0:
94 91c13e54 2004-02-29 devnull case S1:
95 91c13e54 2004-02-29 devnull case S2:
96 91c13e54 2004-02-29 devnull state = S2;
97 91c13e54 2004-02-29 devnull break;
98 91c13e54 2004-02-29 devnull case S3:
99 91c13e54 2004-02-29 devnull case S4:
100 91c13e54 2004-02-29 devnull state = S4;
101 91c13e54 2004-02-29 devnull break;
102 91c13e54 2004-02-29 devnull
103 91c13e54 2004-02-29 devnull case S5:
104 91c13e54 2004-02-29 devnull case S6:
105 91c13e54 2004-02-29 devnull case S7:
106 91c13e54 2004-02-29 devnull state = S7;
107 91c13e54 2004-02-29 devnull ex = ex*10 + (c-'0');
108 91c13e54 2004-02-29 devnull continue;
109 91c13e54 2004-02-29 devnull }
110 91c13e54 2004-02-29 devnull if(na == 0 && c == '0') {
111 91c13e54 2004-02-29 devnull dp--;
112 91c13e54 2004-02-29 devnull continue;
113 91c13e54 2004-02-29 devnull }
114 91c13e54 2004-02-29 devnull if(na < Ndig-50)
115 91c13e54 2004-02-29 devnull a[na++] = c;
116 91c13e54 2004-02-29 devnull continue;
117 91c13e54 2004-02-29 devnull }
118 91c13e54 2004-02-29 devnull switch(c) {
119 91c13e54 2004-02-29 devnull case '\t':
120 91c13e54 2004-02-29 devnull case '\n':
121 91c13e54 2004-02-29 devnull case '\v':
122 91c13e54 2004-02-29 devnull case '\f':
123 91c13e54 2004-02-29 devnull case '\r':
124 91c13e54 2004-02-29 devnull case ' ':
125 91c13e54 2004-02-29 devnull if(state == S0)
126 91c13e54 2004-02-29 devnull continue;
127 91c13e54 2004-02-29 devnull break;
128 91c13e54 2004-02-29 devnull case '-':
129 91c13e54 2004-02-29 devnull if(state == S0)
130 91c13e54 2004-02-29 devnull flag |= Fsign;
131 91c13e54 2004-02-29 devnull else
132 91c13e54 2004-02-29 devnull flag |= Fesign;
133 91c13e54 2004-02-29 devnull case '+':
134 91c13e54 2004-02-29 devnull if(state == S0)
135 91c13e54 2004-02-29 devnull state = S1;
136 91c13e54 2004-02-29 devnull else
137 91c13e54 2004-02-29 devnull if(state == S5)
138 91c13e54 2004-02-29 devnull state = S6;
139 91c13e54 2004-02-29 devnull else
140 91c13e54 2004-02-29 devnull break; /* syntax */
141 91c13e54 2004-02-29 devnull continue;
142 91c13e54 2004-02-29 devnull case '.':
143 91c13e54 2004-02-29 devnull flag |= Fdpoint;
144 91c13e54 2004-02-29 devnull dp = na;
145 91c13e54 2004-02-29 devnull if(state == S0 || state == S1) {
146 91c13e54 2004-02-29 devnull state = S3;
147 91c13e54 2004-02-29 devnull continue;
148 91c13e54 2004-02-29 devnull }
149 91c13e54 2004-02-29 devnull if(state == S2) {
150 91c13e54 2004-02-29 devnull state = S4;
151 91c13e54 2004-02-29 devnull continue;
152 91c13e54 2004-02-29 devnull }
153 91c13e54 2004-02-29 devnull break;
154 91c13e54 2004-02-29 devnull case 'e':
155 91c13e54 2004-02-29 devnull case 'E':
156 91c13e54 2004-02-29 devnull if(state == S2 || state == S4) {
157 91c13e54 2004-02-29 devnull state = S5;
158 91c13e54 2004-02-29 devnull continue;
159 91c13e54 2004-02-29 devnull }
160 91c13e54 2004-02-29 devnull break;
161 91c13e54 2004-02-29 devnull }
162 91c13e54 2004-02-29 devnull break;
163 91c13e54 2004-02-29 devnull }
164 91c13e54 2004-02-29 devnull
165 91c13e54 2004-02-29 devnull /*
166 91c13e54 2004-02-29 devnull * clean up return char-pointer
167 91c13e54 2004-02-29 devnull */
168 91c13e54 2004-02-29 devnull switch(state) {
169 91c13e54 2004-02-29 devnull case S0:
170 91c13e54 2004-02-29 devnull if(xcmp(s, "nan") == 0) {
171 91c13e54 2004-02-29 devnull if(aas != nil)
172 91c13e54 2004-02-29 devnull *aas = s+3;
173 91c13e54 2004-02-29 devnull goto retnan;
174 91c13e54 2004-02-29 devnull }
175 91c13e54 2004-02-29 devnull case S1:
176 91c13e54 2004-02-29 devnull if(xcmp(s, "infinity") == 0) {
177 91c13e54 2004-02-29 devnull if(aas != nil)
178 91c13e54 2004-02-29 devnull *aas = s+8;
179 91c13e54 2004-02-29 devnull goto retinf;
180 91c13e54 2004-02-29 devnull }
181 91c13e54 2004-02-29 devnull if(xcmp(s, "inf") == 0) {
182 91c13e54 2004-02-29 devnull if(aas != nil)
183 91c13e54 2004-02-29 devnull *aas = s+3;
184 91c13e54 2004-02-29 devnull goto retinf;
185 91c13e54 2004-02-29 devnull }
186 91c13e54 2004-02-29 devnull case S3:
187 91c13e54 2004-02-29 devnull if(aas != nil)
188 91c13e54 2004-02-29 devnull *aas = (char*)as;
189 91c13e54 2004-02-29 devnull goto ret0; /* no digits found */
190 91c13e54 2004-02-29 devnull case S6:
191 91c13e54 2004-02-29 devnull s--; /* back over +- */
192 91c13e54 2004-02-29 devnull case S5:
193 91c13e54 2004-02-29 devnull s--; /* back over e */
194 91c13e54 2004-02-29 devnull break;
195 91c13e54 2004-02-29 devnull }
196 91c13e54 2004-02-29 devnull if(aas != nil)
197 91c13e54 2004-02-29 devnull *aas = s;
198 91c13e54 2004-02-29 devnull
199 91c13e54 2004-02-29 devnull if(flag & Fdpoint)
200 91c13e54 2004-02-29 devnull while(na > 0 && a[na-1] == '0')
201 91c13e54 2004-02-29 devnull na--;
202 91c13e54 2004-02-29 devnull if(na == 0)
203 91c13e54 2004-02-29 devnull goto ret0; /* zero */
204 91c13e54 2004-02-29 devnull a[na] = 0;
205 91c13e54 2004-02-29 devnull if(!(flag & Fdpoint))
206 91c13e54 2004-02-29 devnull dp = na;
207 91c13e54 2004-02-29 devnull if(flag & Fesign)
208 91c13e54 2004-02-29 devnull ex = -ex;
209 91c13e54 2004-02-29 devnull dp += ex;
210 91c13e54 2004-02-29 devnull if(dp < -Maxe){
211 91c13e54 2004-02-29 devnull errno = ERANGE;
212 91c13e54 2004-02-29 devnull goto ret0; /* underflow by exp */
213 91c13e54 2004-02-29 devnull } else
214 91c13e54 2004-02-29 devnull if(dp > +Maxe)
215 91c13e54 2004-02-29 devnull goto retinf; /* overflow by exp */
216 91c13e54 2004-02-29 devnull
217 91c13e54 2004-02-29 devnull /*
218 91c13e54 2004-02-29 devnull * normalize the decimal ascii number
219 91c13e54 2004-02-29 devnull * to range .[5-9][0-9]* e0
220 91c13e54 2004-02-29 devnull */
221 91c13e54 2004-02-29 devnull bp = 0; /* binary exponent */
222 91c13e54 2004-02-29 devnull while(dp > 0)
223 91c13e54 2004-02-29 devnull divascii(a, &na, &dp, &bp);
224 91c13e54 2004-02-29 devnull while(dp < 0 || a[0] < '5')
225 91c13e54 2004-02-29 devnull mulascii(a, &na, &dp, &bp);
226 91c13e54 2004-02-29 devnull
227 91c13e54 2004-02-29 devnull /* close approx by naive conversion */
228 91c13e54 2004-02-29 devnull mid[0] = 0;
229 91c13e54 2004-02-29 devnull mid[1] = 1;
230 85231fd8 2006-05-21 devnull for(i=0; (c=a[i]) != '\0'; i++) {
231 91c13e54 2004-02-29 devnull mid[0] = mid[0]*10 + (c-'0');
232 91c13e54 2004-02-29 devnull mid[1] = mid[1]*10;
233 91c13e54 2004-02-29 devnull if(i >= 8)
234 91c13e54 2004-02-29 devnull break;
235 91c13e54 2004-02-29 devnull }
236 91c13e54 2004-02-29 devnull low[0] = umuldiv(mid[0], One, mid[1]);
237 91c13e54 2004-02-29 devnull hig[0] = umuldiv(mid[0]+1, One, mid[1]);
238 91c13e54 2004-02-29 devnull for(i=1; i<Prec; i++) {
239 91c13e54 2004-02-29 devnull low[i] = 0;
240 91c13e54 2004-02-29 devnull hig[i] = One-1;
241 91c13e54 2004-02-29 devnull }
242 91c13e54 2004-02-29 devnull
243 91c13e54 2004-02-29 devnull /* binary search for closest mantissa */
244 91c13e54 2004-02-29 devnull for(;;) {
245 91c13e54 2004-02-29 devnull /* mid = (hig + low) / 2 */
246 91c13e54 2004-02-29 devnull c = 0;
247 91c13e54 2004-02-29 devnull for(i=0; i<Prec; i++) {
248 91c13e54 2004-02-29 devnull mid[i] = hig[i] + low[i];
249 91c13e54 2004-02-29 devnull if(c)
250 91c13e54 2004-02-29 devnull mid[i] += One;
251 91c13e54 2004-02-29 devnull c = mid[i] & 1;
252 91c13e54 2004-02-29 devnull mid[i] >>= 1;
253 91c13e54 2004-02-29 devnull }
254 91c13e54 2004-02-29 devnull frnorm(mid);
255 91c13e54 2004-02-29 devnull
256 91c13e54 2004-02-29 devnull /* compare */
257 91c13e54 2004-02-29 devnull c = fpcmp(a, mid);
258 91c13e54 2004-02-29 devnull if(c > 0) {
259 91c13e54 2004-02-29 devnull c = 1;
260 91c13e54 2004-02-29 devnull for(i=0; i<Prec; i++)
261 91c13e54 2004-02-29 devnull if(low[i] != mid[i]) {
262 91c13e54 2004-02-29 devnull c = 0;
263 91c13e54 2004-02-29 devnull low[i] = mid[i];
264 91c13e54 2004-02-29 devnull }
265 91c13e54 2004-02-29 devnull if(c)
266 91c13e54 2004-02-29 devnull break; /* between mid and hig */
267 91c13e54 2004-02-29 devnull continue;
268 91c13e54 2004-02-29 devnull }
269 91c13e54 2004-02-29 devnull if(c < 0) {
270 91c13e54 2004-02-29 devnull for(i=0; i<Prec; i++)
271 91c13e54 2004-02-29 devnull hig[i] = mid[i];
272 91c13e54 2004-02-29 devnull continue;
273 91c13e54 2004-02-29 devnull }
274 91c13e54 2004-02-29 devnull
275 91c13e54 2004-02-29 devnull /* only hard part is if even/odd roundings wants to go up */
276 91c13e54 2004-02-29 devnull c = mid[Prec-1] & (Sigbit-1);
277 91c13e54 2004-02-29 devnull if(c == Sigbit/2 && (mid[Prec-1]&Sigbit) == 0)
278 91c13e54 2004-02-29 devnull mid[Prec-1] -= c;
279 91c13e54 2004-02-29 devnull break; /* exactly mid */
280 91c13e54 2004-02-29 devnull }
281 91c13e54 2004-02-29 devnull
282 91c13e54 2004-02-29 devnull /* normal rounding applies */
283 91c13e54 2004-02-29 devnull c = mid[Prec-1] & (Sigbit-1);
284 91c13e54 2004-02-29 devnull mid[Prec-1] -= c;
285 91c13e54 2004-02-29 devnull if(c >= Sigbit/2) {
286 91c13e54 2004-02-29 devnull mid[Prec-1] += Sigbit;
287 91c13e54 2004-02-29 devnull frnorm(mid);
288 91c13e54 2004-02-29 devnull }
289 91c13e54 2004-02-29 devnull goto out;
290 91c13e54 2004-02-29 devnull
291 91c13e54 2004-02-29 devnull ret0:
292 91c13e54 2004-02-29 devnull return 0;
293 91c13e54 2004-02-29 devnull
294 91c13e54 2004-02-29 devnull retnan:
295 91c13e54 2004-02-29 devnull return __NaN();
296 91c13e54 2004-02-29 devnull
297 91c13e54 2004-02-29 devnull retinf:
298 91c13e54 2004-02-29 devnull /*
299 91c13e54 2004-02-29 devnull * Unix strtod requires these. Plan 9 would return Inf(0) or Inf(-1). */
300 91c13e54 2004-02-29 devnull errno = ERANGE;
301 91c13e54 2004-02-29 devnull if(flag & Fsign)
302 91c13e54 2004-02-29 devnull return -HUGE_VAL;
303 91c13e54 2004-02-29 devnull return HUGE_VAL;
304 91c13e54 2004-02-29 devnull
305 91c13e54 2004-02-29 devnull out:
306 91c13e54 2004-02-29 devnull d = 0;
307 91c13e54 2004-02-29 devnull for(i=0; i<Prec; i++)
308 91c13e54 2004-02-29 devnull d = d*One + mid[i];
309 91c13e54 2004-02-29 devnull if(flag & Fsign)
310 91c13e54 2004-02-29 devnull d = -d;
311 91c13e54 2004-02-29 devnull d = ldexp(d, bp - Prec*Nbits);
312 91c13e54 2004-02-29 devnull if(d == 0){ /* underflow */
313 91c13e54 2004-02-29 devnull errno = ERANGE;
314 91c13e54 2004-02-29 devnull }
315 91c13e54 2004-02-29 devnull return d;
316 91c13e54 2004-02-29 devnull }
317 91c13e54 2004-02-29 devnull
318 91c13e54 2004-02-29 devnull static void
319 91c13e54 2004-02-29 devnull frnorm(ulong *f)
320 91c13e54 2004-02-29 devnull {
321 91c13e54 2004-02-29 devnull int i, c;
322 91c13e54 2004-02-29 devnull
323 91c13e54 2004-02-29 devnull c = 0;
324 91c13e54 2004-02-29 devnull for(i=Prec-1; i>0; i--) {
325 91c13e54 2004-02-29 devnull f[i] += c;
326 91c13e54 2004-02-29 devnull c = f[i] >> Nbits;
327 91c13e54 2004-02-29 devnull f[i] &= One-1;
328 91c13e54 2004-02-29 devnull }
329 91c13e54 2004-02-29 devnull f[0] += c;
330 91c13e54 2004-02-29 devnull }
331 91c13e54 2004-02-29 devnull
332 91c13e54 2004-02-29 devnull static int
333 91c13e54 2004-02-29 devnull fpcmp(char *a, ulong* f)
334 91c13e54 2004-02-29 devnull {
335 91c13e54 2004-02-29 devnull ulong tf[Prec];
336 91c13e54 2004-02-29 devnull int i, d, c;
337 91c13e54 2004-02-29 devnull
338 91c13e54 2004-02-29 devnull for(i=0; i<Prec; i++)
339 91c13e54 2004-02-29 devnull tf[i] = f[i];
340 91c13e54 2004-02-29 devnull
341 91c13e54 2004-02-29 devnull for(;;) {
342 91c13e54 2004-02-29 devnull /* tf *= 10 */
343 91c13e54 2004-02-29 devnull for(i=0; i<Prec; i++)
344 91c13e54 2004-02-29 devnull tf[i] = tf[i]*10;
345 91c13e54 2004-02-29 devnull frnorm(tf);
346 91c13e54 2004-02-29 devnull d = (tf[0] >> Nbits) + '0';
347 91c13e54 2004-02-29 devnull tf[0] &= One-1;
348 91c13e54 2004-02-29 devnull
349 91c13e54 2004-02-29 devnull /* compare next digit */
350 91c13e54 2004-02-29 devnull c = *a;
351 91c13e54 2004-02-29 devnull if(c == 0) {
352 91c13e54 2004-02-29 devnull if('0' < d)
353 91c13e54 2004-02-29 devnull return -1;
354 91c13e54 2004-02-29 devnull if(tf[0] != 0)
355 91c13e54 2004-02-29 devnull goto cont;
356 91c13e54 2004-02-29 devnull for(i=1; i<Prec; i++)
357 91c13e54 2004-02-29 devnull if(tf[i] != 0)
358 91c13e54 2004-02-29 devnull goto cont;
359 91c13e54 2004-02-29 devnull return 0;
360 91c13e54 2004-02-29 devnull }
361 91c13e54 2004-02-29 devnull if(c > d)
362 91c13e54 2004-02-29 devnull return +1;
363 91c13e54 2004-02-29 devnull if(c < d)
364 91c13e54 2004-02-29 devnull return -1;
365 91c13e54 2004-02-29 devnull a++;
366 91c13e54 2004-02-29 devnull cont:;
367 91c13e54 2004-02-29 devnull }
368 91c13e54 2004-02-29 devnull }
369 91c13e54 2004-02-29 devnull
370 91c13e54 2004-02-29 devnull static void
371 91c13e54 2004-02-29 devnull divby(char *a, int *na, int b)
372 91c13e54 2004-02-29 devnull {
373 91c13e54 2004-02-29 devnull int n, c;
374 91c13e54 2004-02-29 devnull char *p;
375 91c13e54 2004-02-29 devnull
376 91c13e54 2004-02-29 devnull p = a;
377 91c13e54 2004-02-29 devnull n = 0;
378 91c13e54 2004-02-29 devnull while(n>>b == 0) {
379 91c13e54 2004-02-29 devnull c = *a++;
380 91c13e54 2004-02-29 devnull if(c == 0) {
381 91c13e54 2004-02-29 devnull while(n) {
382 91c13e54 2004-02-29 devnull c = n*10;
383 91c13e54 2004-02-29 devnull if(c>>b)
384 91c13e54 2004-02-29 devnull break;
385 91c13e54 2004-02-29 devnull n = c;
386 91c13e54 2004-02-29 devnull }
387 91c13e54 2004-02-29 devnull goto xx;
388 91c13e54 2004-02-29 devnull }
389 91c13e54 2004-02-29 devnull n = n*10 + c-'0';
390 91c13e54 2004-02-29 devnull (*na)--;
391 91c13e54 2004-02-29 devnull }
392 91c13e54 2004-02-29 devnull for(;;) {
393 91c13e54 2004-02-29 devnull c = n>>b;
394 91c13e54 2004-02-29 devnull n -= c<<b;
395 91c13e54 2004-02-29 devnull *p++ = c + '0';
396 91c13e54 2004-02-29 devnull c = *a++;
397 91c13e54 2004-02-29 devnull if(c == 0)
398 91c13e54 2004-02-29 devnull break;
399 91c13e54 2004-02-29 devnull n = n*10 + c-'0';
400 91c13e54 2004-02-29 devnull }
401 91c13e54 2004-02-29 devnull (*na)++;
402 91c13e54 2004-02-29 devnull xx:
403 91c13e54 2004-02-29 devnull while(n) {
404 91c13e54 2004-02-29 devnull n = n*10;
405 91c13e54 2004-02-29 devnull c = n>>b;
406 91c13e54 2004-02-29 devnull n -= c<<b;
407 91c13e54 2004-02-29 devnull *p++ = c + '0';
408 91c13e54 2004-02-29 devnull (*na)++;
409 91c13e54 2004-02-29 devnull }
410 91c13e54 2004-02-29 devnull *p = 0;
411 91c13e54 2004-02-29 devnull }
412 91c13e54 2004-02-29 devnull
413 91c13e54 2004-02-29 devnull static Tab tab1[] =
414 91c13e54 2004-02-29 devnull {
415 91c13e54 2004-02-29 devnull 1, 0, "",
416 91c13e54 2004-02-29 devnull 3, 1, "7",
417 91c13e54 2004-02-29 devnull 6, 2, "63",
418 91c13e54 2004-02-29 devnull 9, 3, "511",
419 91c13e54 2004-02-29 devnull 13, 4, "8191",
420 91c13e54 2004-02-29 devnull 16, 5, "65535",
421 91c13e54 2004-02-29 devnull 19, 6, "524287",
422 91c13e54 2004-02-29 devnull 23, 7, "8388607",
423 91c13e54 2004-02-29 devnull 26, 8, "67108863",
424 91c13e54 2004-02-29 devnull 27, 9, "134217727",
425 91c13e54 2004-02-29 devnull };
426 91c13e54 2004-02-29 devnull
427 91c13e54 2004-02-29 devnull static void
428 91c13e54 2004-02-29 devnull divascii(char *a, int *na, int *dp, int *bp)
429 91c13e54 2004-02-29 devnull {
430 91c13e54 2004-02-29 devnull int b, d;
431 91c13e54 2004-02-29 devnull Tab *t;
432 91c13e54 2004-02-29 devnull
433 91c13e54 2004-02-29 devnull d = *dp;
434 91c13e54 2004-02-29 devnull if(d >= (int)(nelem(tab1)))
435 91c13e54 2004-02-29 devnull d = (int)(nelem(tab1))-1;
436 91c13e54 2004-02-29 devnull t = tab1 + d;
437 91c13e54 2004-02-29 devnull b = t->bp;
438 91c13e54 2004-02-29 devnull if(memcmp(a, t->cmp, t->siz) > 0)
439 91c13e54 2004-02-29 devnull d--;
440 91c13e54 2004-02-29 devnull *dp -= d;
441 91c13e54 2004-02-29 devnull *bp += b;
442 91c13e54 2004-02-29 devnull divby(a, na, b);
443 91c13e54 2004-02-29 devnull }
444 91c13e54 2004-02-29 devnull
445 91c13e54 2004-02-29 devnull static void
446 91c13e54 2004-02-29 devnull mulby(char *a, char *p, char *q, int b)
447 91c13e54 2004-02-29 devnull {
448 91c13e54 2004-02-29 devnull int n, c;
449 91c13e54 2004-02-29 devnull
450 91c13e54 2004-02-29 devnull n = 0;
451 91c13e54 2004-02-29 devnull *p = 0;
452 91c13e54 2004-02-29 devnull for(;;) {
453 91c13e54 2004-02-29 devnull q--;
454 91c13e54 2004-02-29 devnull if(q < a)
455 91c13e54 2004-02-29 devnull break;
456 91c13e54 2004-02-29 devnull c = *q - '0';
457 91c13e54 2004-02-29 devnull c = (c<<b) + n;
458 91c13e54 2004-02-29 devnull n = c/10;
459 91c13e54 2004-02-29 devnull c -= n*10;
460 91c13e54 2004-02-29 devnull p--;
461 91c13e54 2004-02-29 devnull *p = c + '0';
462 91c13e54 2004-02-29 devnull }
463 91c13e54 2004-02-29 devnull while(n) {
464 91c13e54 2004-02-29 devnull c = n;
465 91c13e54 2004-02-29 devnull n = c/10;
466 91c13e54 2004-02-29 devnull c -= n*10;
467 91c13e54 2004-02-29 devnull p--;
468 91c13e54 2004-02-29 devnull *p = c + '0';
469 91c13e54 2004-02-29 devnull }
470 91c13e54 2004-02-29 devnull }
471 91c13e54 2004-02-29 devnull
472 91c13e54 2004-02-29 devnull static Tab tab2[] =
473 91c13e54 2004-02-29 devnull {
474 91c13e54 2004-02-29 devnull 1, 1, "", /* dp = 0-0 */
475 91c13e54 2004-02-29 devnull 3, 3, "125",
476 91c13e54 2004-02-29 devnull 6, 5, "15625",
477 91c13e54 2004-02-29 devnull 9, 7, "1953125",
478 91c13e54 2004-02-29 devnull 13, 10, "1220703125",
479 91c13e54 2004-02-29 devnull 16, 12, "152587890625",
480 91c13e54 2004-02-29 devnull 19, 14, "19073486328125",
481 91c13e54 2004-02-29 devnull 23, 17, "11920928955078125",
482 91c13e54 2004-02-29 devnull 26, 19, "1490116119384765625",
483 91c13e54 2004-02-29 devnull 27, 19, "7450580596923828125", /* dp 8-9 */
484 91c13e54 2004-02-29 devnull };
485 91c13e54 2004-02-29 devnull
486 91c13e54 2004-02-29 devnull static void
487 91c13e54 2004-02-29 devnull mulascii(char *a, int *na, int *dp, int *bp)
488 91c13e54 2004-02-29 devnull {
489 91c13e54 2004-02-29 devnull char *p;
490 91c13e54 2004-02-29 devnull int d, b;
491 91c13e54 2004-02-29 devnull Tab *t;
492 91c13e54 2004-02-29 devnull
493 91c13e54 2004-02-29 devnull d = -*dp;
494 91c13e54 2004-02-29 devnull if(d >= (int)(nelem(tab2)))
495 91c13e54 2004-02-29 devnull d = (int)(nelem(tab2))-1;
496 91c13e54 2004-02-29 devnull t = tab2 + d;
497 91c13e54 2004-02-29 devnull b = t->bp;
498 91c13e54 2004-02-29 devnull if(memcmp(a, t->cmp, t->siz) < 0)
499 91c13e54 2004-02-29 devnull d--;
500 91c13e54 2004-02-29 devnull p = a + *na;
501 91c13e54 2004-02-29 devnull *bp -= b;
502 91c13e54 2004-02-29 devnull *dp += d;
503 91c13e54 2004-02-29 devnull *na += d;
504 91c13e54 2004-02-29 devnull mulby(a, p+d, p, b);
505 91c13e54 2004-02-29 devnull }
506 91c13e54 2004-02-29 devnull
507 91c13e54 2004-02-29 devnull static int
508 91c13e54 2004-02-29 devnull xcmp(char *a, char *b)
509 91c13e54 2004-02-29 devnull {
510 91c13e54 2004-02-29 devnull int c1, c2;
511 91c13e54 2004-02-29 devnull
512 85231fd8 2006-05-21 devnull while((c1 = *b++) != '\0') {
513 91c13e54 2004-02-29 devnull c2 = *a++;
514 91c13e54 2004-02-29 devnull if(isupper(c2))
515 91c13e54 2004-02-29 devnull c2 = tolower(c2);
516 91c13e54 2004-02-29 devnull if(c1 != c2)
517 91c13e54 2004-02-29 devnull return 1;
518 91c13e54 2004-02-29 devnull }
519 91c13e54 2004-02-29 devnull return 0;
520 91c13e54 2004-02-29 devnull }