Blame


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