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