xref: /plan9/sys/src/ape/lib/ap/stdio/_fconv.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1*3e12c5d1SDavid du Colombier /* Common routines for _dtoa and strtod */
2*3e12c5d1SDavid du Colombier 
3*3e12c5d1SDavid du Colombier #include "fconv.h"
4*3e12c5d1SDavid du Colombier 
5*3e12c5d1SDavid du Colombier #ifdef DEBUG
6*3e12c5d1SDavid du Colombier #include <stdio.h>
7*3e12c5d1SDavid du Colombier #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
8*3e12c5d1SDavid du Colombier #endif
9*3e12c5d1SDavid du Colombier 
10*3e12c5d1SDavid du Colombier  double
11*3e12c5d1SDavid du Colombier _tens[] = {
12*3e12c5d1SDavid du Colombier 		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
13*3e12c5d1SDavid du Colombier 		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
14*3e12c5d1SDavid du Colombier 		1e20, 1e21, 1e22
15*3e12c5d1SDavid du Colombier #ifdef VAX
16*3e12c5d1SDavid du Colombier 		, 1e23, 1e24
17*3e12c5d1SDavid du Colombier #endif
18*3e12c5d1SDavid du Colombier 		};
19*3e12c5d1SDavid du Colombier 
20*3e12c5d1SDavid du Colombier 
21*3e12c5d1SDavid du Colombier #ifdef IEEE_Arith
22*3e12c5d1SDavid du Colombier double _bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
23*3e12c5d1SDavid du Colombier double _tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
24*3e12c5d1SDavid du Colombier #else
25*3e12c5d1SDavid du Colombier #ifdef IBM
26*3e12c5d1SDavid du Colombier double _bigtens[] = { 1e16, 1e32, 1e64 };
27*3e12c5d1SDavid du Colombier double _tinytens[] = { 1e-16, 1e-32, 1e-64 };
28*3e12c5d1SDavid du Colombier #else
29*3e12c5d1SDavid du Colombier double _bigtens[] = { 1e16, 1e32 };
30*3e12c5d1SDavid du Colombier double _tinytens[] = { 1e-16, 1e-32 };
31*3e12c5d1SDavid du Colombier #endif
32*3e12c5d1SDavid du Colombier #endif
33*3e12c5d1SDavid du Colombier 
34*3e12c5d1SDavid du Colombier  static Bigint *freelist[Kmax+1];
35*3e12c5d1SDavid du Colombier 
36*3e12c5d1SDavid du Colombier  Bigint *
_Balloc(int k)37*3e12c5d1SDavid du Colombier _Balloc(int k)
38*3e12c5d1SDavid du Colombier {
39*3e12c5d1SDavid du Colombier 	int x;
40*3e12c5d1SDavid du Colombier 	Bigint *rv;
41*3e12c5d1SDavid du Colombier 
42*3e12c5d1SDavid du Colombier 	if (rv = freelist[k]) {
43*3e12c5d1SDavid du Colombier 		freelist[k] = rv->next;
44*3e12c5d1SDavid du Colombier 		}
45*3e12c5d1SDavid du Colombier 	else {
46*3e12c5d1SDavid du Colombier 		x = 1 << k;
47*3e12c5d1SDavid du Colombier 		rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(long));
48*3e12c5d1SDavid du Colombier 		rv->k = k;
49*3e12c5d1SDavid du Colombier 		rv->maxwds = x;
50*3e12c5d1SDavid du Colombier 		}
51*3e12c5d1SDavid du Colombier 	rv->sign = rv->wds = 0;
52*3e12c5d1SDavid du Colombier 	return rv;
53*3e12c5d1SDavid du Colombier 	}
54*3e12c5d1SDavid du Colombier 
55*3e12c5d1SDavid du Colombier  void
_Bfree(Bigint * v)56*3e12c5d1SDavid du Colombier _Bfree(Bigint *v)
57*3e12c5d1SDavid du Colombier {
58*3e12c5d1SDavid du Colombier 	if (v) {
59*3e12c5d1SDavid du Colombier 		v->next = freelist[v->k];
60*3e12c5d1SDavid du Colombier 		freelist[v->k] = v;
61*3e12c5d1SDavid du Colombier 		}
62*3e12c5d1SDavid du Colombier 	}
63*3e12c5d1SDavid du Colombier 
64*3e12c5d1SDavid du Colombier 
65*3e12c5d1SDavid du Colombier  Bigint *
_multadd(Bigint * b,int m,int a)66*3e12c5d1SDavid du Colombier _multadd(Bigint *b, int m, int a)	/* multiply by m and add a */
67*3e12c5d1SDavid du Colombier {
68*3e12c5d1SDavid du Colombier 	int i, wds;
69*3e12c5d1SDavid du Colombier 	unsigned long *x, y;
70*3e12c5d1SDavid du Colombier #ifdef Pack_32
71*3e12c5d1SDavid du Colombier 	unsigned long xi, z;
72*3e12c5d1SDavid du Colombier #endif
73*3e12c5d1SDavid du Colombier 	Bigint *b1;
74*3e12c5d1SDavid du Colombier 
75*3e12c5d1SDavid du Colombier 	wds = b->wds;
76*3e12c5d1SDavid du Colombier 	x = b->x;
77*3e12c5d1SDavid du Colombier 	i = 0;
78*3e12c5d1SDavid du Colombier 	do {
79*3e12c5d1SDavid du Colombier #ifdef Pack_32
80*3e12c5d1SDavid du Colombier 		xi = *x;
81*3e12c5d1SDavid du Colombier 		y = (xi & 0xffff) * m + a;
82*3e12c5d1SDavid du Colombier 		z = (xi >> 16) * m + (y >> 16);
83*3e12c5d1SDavid du Colombier 		a = (int)(z >> 16);
84*3e12c5d1SDavid du Colombier 		*x++ = (z << 16) + (y & 0xffff);
85*3e12c5d1SDavid du Colombier #else
86*3e12c5d1SDavid du Colombier 		y = *x * m + a;
87*3e12c5d1SDavid du Colombier 		a = (int)(y >> 16);
88*3e12c5d1SDavid du Colombier 		*x++ = y & 0xffff;
89*3e12c5d1SDavid du Colombier #endif
90*3e12c5d1SDavid du Colombier 		}
91*3e12c5d1SDavid du Colombier 		while(++i < wds);
92*3e12c5d1SDavid du Colombier 	if (a) {
93*3e12c5d1SDavid du Colombier 		if (wds >= b->maxwds) {
94*3e12c5d1SDavid du Colombier 			b1 = Balloc(b->k+1);
95*3e12c5d1SDavid du Colombier 			Bcopy(b1, b);
96*3e12c5d1SDavid du Colombier 			Bfree(b);
97*3e12c5d1SDavid du Colombier 			b = b1;
98*3e12c5d1SDavid du Colombier 			}
99*3e12c5d1SDavid du Colombier 		b->x[wds++] = a;
100*3e12c5d1SDavid du Colombier 		b->wds = wds;
101*3e12c5d1SDavid du Colombier 		}
102*3e12c5d1SDavid du Colombier 	return b;
103*3e12c5d1SDavid du Colombier 	}
104*3e12c5d1SDavid du Colombier 
105*3e12c5d1SDavid du Colombier  int
_hi0bits(register unsigned long x)106*3e12c5d1SDavid du Colombier _hi0bits(register unsigned long x)
107*3e12c5d1SDavid du Colombier {
108*3e12c5d1SDavid du Colombier 	register int k = 0;
109*3e12c5d1SDavid du Colombier 
110*3e12c5d1SDavid du Colombier 	if (!(x & 0xffff0000)) {
111*3e12c5d1SDavid du Colombier 		k = 16;
112*3e12c5d1SDavid du Colombier 		x <<= 16;
113*3e12c5d1SDavid du Colombier 		}
114*3e12c5d1SDavid du Colombier 	if (!(x & 0xff000000)) {
115*3e12c5d1SDavid du Colombier 		k += 8;
116*3e12c5d1SDavid du Colombier 		x <<= 8;
117*3e12c5d1SDavid du Colombier 		}
118*3e12c5d1SDavid du Colombier 	if (!(x & 0xf0000000)) {
119*3e12c5d1SDavid du Colombier 		k += 4;
120*3e12c5d1SDavid du Colombier 		x <<= 4;
121*3e12c5d1SDavid du Colombier 		}
122*3e12c5d1SDavid du Colombier 	if (!(x & 0xc0000000)) {
123*3e12c5d1SDavid du Colombier 		k += 2;
124*3e12c5d1SDavid du Colombier 		x <<= 2;
125*3e12c5d1SDavid du Colombier 		}
126*3e12c5d1SDavid du Colombier 	if (!(x & 0x80000000)) {
127*3e12c5d1SDavid du Colombier 		k++;
128*3e12c5d1SDavid du Colombier 		if (!(x & 0x40000000))
129*3e12c5d1SDavid du Colombier 			return 32;
130*3e12c5d1SDavid du Colombier 		}
131*3e12c5d1SDavid du Colombier 	return k;
132*3e12c5d1SDavid du Colombier 	}
133*3e12c5d1SDavid du Colombier 
134*3e12c5d1SDavid du Colombier  static int
lo0bits(unsigned long * y)135*3e12c5d1SDavid du Colombier lo0bits(unsigned long *y)
136*3e12c5d1SDavid du Colombier {
137*3e12c5d1SDavid du Colombier 	register int k;
138*3e12c5d1SDavid du Colombier 	register unsigned long x = *y;
139*3e12c5d1SDavid du Colombier 
140*3e12c5d1SDavid du Colombier 	if (x & 7) {
141*3e12c5d1SDavid du Colombier 		if (x & 1)
142*3e12c5d1SDavid du Colombier 			return 0;
143*3e12c5d1SDavid du Colombier 		if (x & 2) {
144*3e12c5d1SDavid du Colombier 			*y = x >> 1;
145*3e12c5d1SDavid du Colombier 			return 1;
146*3e12c5d1SDavid du Colombier 			}
147*3e12c5d1SDavid du Colombier 		*y = x >> 2;
148*3e12c5d1SDavid du Colombier 		return 2;
149*3e12c5d1SDavid du Colombier 		}
150*3e12c5d1SDavid du Colombier 	k = 0;
151*3e12c5d1SDavid du Colombier 	if (!(x & 0xffff)) {
152*3e12c5d1SDavid du Colombier 		k = 16;
153*3e12c5d1SDavid du Colombier 		x >>= 16;
154*3e12c5d1SDavid du Colombier 		}
155*3e12c5d1SDavid du Colombier 	if (!(x & 0xff)) {
156*3e12c5d1SDavid du Colombier 		k += 8;
157*3e12c5d1SDavid du Colombier 		x >>= 8;
158*3e12c5d1SDavid du Colombier 		}
159*3e12c5d1SDavid du Colombier 	if (!(x & 0xf)) {
160*3e12c5d1SDavid du Colombier 		k += 4;
161*3e12c5d1SDavid du Colombier 		x >>= 4;
162*3e12c5d1SDavid du Colombier 		}
163*3e12c5d1SDavid du Colombier 	if (!(x & 0x3)) {
164*3e12c5d1SDavid du Colombier 		k += 2;
165*3e12c5d1SDavid du Colombier 		x >>= 2;
166*3e12c5d1SDavid du Colombier 		}
167*3e12c5d1SDavid du Colombier 	if (!(x & 1)) {
168*3e12c5d1SDavid du Colombier 		k++;
169*3e12c5d1SDavid du Colombier 		x >>= 1;
170*3e12c5d1SDavid du Colombier 		if (!x & 1)
171*3e12c5d1SDavid du Colombier 			return 32;
172*3e12c5d1SDavid du Colombier 		}
173*3e12c5d1SDavid du Colombier 	*y = x;
174*3e12c5d1SDavid du Colombier 	return k;
175*3e12c5d1SDavid du Colombier 	}
176*3e12c5d1SDavid du Colombier 
177*3e12c5d1SDavid du Colombier  Bigint *
_i2b(int i)178*3e12c5d1SDavid du Colombier _i2b(int i)
179*3e12c5d1SDavid du Colombier {
180*3e12c5d1SDavid du Colombier 	Bigint *b;
181*3e12c5d1SDavid du Colombier 
182*3e12c5d1SDavid du Colombier 	b = Balloc(1);
183*3e12c5d1SDavid du Colombier 	b->x[0] = i;
184*3e12c5d1SDavid du Colombier 	b->wds = 1;
185*3e12c5d1SDavid du Colombier 	return b;
186*3e12c5d1SDavid du Colombier 	}
187*3e12c5d1SDavid du Colombier 
188*3e12c5d1SDavid du Colombier  Bigint *
_mult(Bigint * a,Bigint * b)189*3e12c5d1SDavid du Colombier _mult(Bigint *a, Bigint *b)
190*3e12c5d1SDavid du Colombier {
191*3e12c5d1SDavid du Colombier 	Bigint *c;
192*3e12c5d1SDavid du Colombier 	int k, wa, wb, wc;
193*3e12c5d1SDavid du Colombier 	unsigned long carry, y, z;
194*3e12c5d1SDavid du Colombier 	unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
195*3e12c5d1SDavid du Colombier #ifdef Pack_32
196*3e12c5d1SDavid du Colombier 	unsigned long z2;
197*3e12c5d1SDavid du Colombier #endif
198*3e12c5d1SDavid du Colombier 
199*3e12c5d1SDavid du Colombier 	if (a->wds < b->wds) {
200*3e12c5d1SDavid du Colombier 		c = a;
201*3e12c5d1SDavid du Colombier 		a = b;
202*3e12c5d1SDavid du Colombier 		b = c;
203*3e12c5d1SDavid du Colombier 		}
204*3e12c5d1SDavid du Colombier 	k = a->k;
205*3e12c5d1SDavid du Colombier 	wa = a->wds;
206*3e12c5d1SDavid du Colombier 	wb = b->wds;
207*3e12c5d1SDavid du Colombier 	wc = wa + wb;
208*3e12c5d1SDavid du Colombier 	if (wc > a->maxwds)
209*3e12c5d1SDavid du Colombier 		k++;
210*3e12c5d1SDavid du Colombier 	c = Balloc(k);
211*3e12c5d1SDavid du Colombier 	for(x = c->x, xa = x + wc; x < xa; x++)
212*3e12c5d1SDavid du Colombier 		*x = 0;
213*3e12c5d1SDavid du Colombier 	xa = a->x;
214*3e12c5d1SDavid du Colombier 	xae = xa + wa;
215*3e12c5d1SDavid du Colombier 	xb = b->x;
216*3e12c5d1SDavid du Colombier 	xbe = xb + wb;
217*3e12c5d1SDavid du Colombier 	xc0 = c->x;
218*3e12c5d1SDavid du Colombier #ifdef Pack_32
219*3e12c5d1SDavid du Colombier 	for(; xb < xbe; xb++, xc0++) {
220*3e12c5d1SDavid du Colombier 		if (y = *xb & 0xffff) {
221*3e12c5d1SDavid du Colombier 			x = xa;
222*3e12c5d1SDavid du Colombier 			xc = xc0;
223*3e12c5d1SDavid du Colombier 			carry = 0;
224*3e12c5d1SDavid du Colombier 			do {
225*3e12c5d1SDavid du Colombier 				z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
226*3e12c5d1SDavid du Colombier 				carry = z >> 16;
227*3e12c5d1SDavid du Colombier 				z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
228*3e12c5d1SDavid du Colombier 				carry = z2 >> 16;
229*3e12c5d1SDavid du Colombier 				Storeinc(xc, z2, z);
230*3e12c5d1SDavid du Colombier 				}
231*3e12c5d1SDavid du Colombier 				while(x < xae);
232*3e12c5d1SDavid du Colombier 			*xc = carry;
233*3e12c5d1SDavid du Colombier 			}
234*3e12c5d1SDavid du Colombier 		if (y = *xb >> 16) {
235*3e12c5d1SDavid du Colombier 			x = xa;
236*3e12c5d1SDavid du Colombier 			xc = xc0;
237*3e12c5d1SDavid du Colombier 			carry = 0;
238*3e12c5d1SDavid du Colombier 			z2 = *xc;
239*3e12c5d1SDavid du Colombier 			do {
240*3e12c5d1SDavid du Colombier 				z = (*x & 0xffff) * y + (*xc >> 16) + carry;
241*3e12c5d1SDavid du Colombier 				carry = z >> 16;
242*3e12c5d1SDavid du Colombier 				Storeinc(xc, z, z2);
243*3e12c5d1SDavid du Colombier 				z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
244*3e12c5d1SDavid du Colombier 				carry = z2 >> 16;
245*3e12c5d1SDavid du Colombier 				}
246*3e12c5d1SDavid du Colombier 				while(x < xae);
247*3e12c5d1SDavid du Colombier 			*xc = z2;
248*3e12c5d1SDavid du Colombier 			}
249*3e12c5d1SDavid du Colombier 		}
250*3e12c5d1SDavid du Colombier #else
251*3e12c5d1SDavid du Colombier 	for(; xb < xbe; xc0++) {
252*3e12c5d1SDavid du Colombier 		if (y = *xb++) {
253*3e12c5d1SDavid du Colombier 			x = xa;
254*3e12c5d1SDavid du Colombier 			xc = xc0;
255*3e12c5d1SDavid du Colombier 			carry = 0;
256*3e12c5d1SDavid du Colombier 			do {
257*3e12c5d1SDavid du Colombier 				z = *x++ * y + *xc + carry;
258*3e12c5d1SDavid du Colombier 				carry = z >> 16;
259*3e12c5d1SDavid du Colombier 				*xc++ = z & 0xffff;
260*3e12c5d1SDavid du Colombier 				}
261*3e12c5d1SDavid du Colombier 				while(x < xae);
262*3e12c5d1SDavid du Colombier 			*xc = carry;
263*3e12c5d1SDavid du Colombier 			}
264*3e12c5d1SDavid du Colombier 		}
265*3e12c5d1SDavid du Colombier #endif
266*3e12c5d1SDavid du Colombier 	for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
267*3e12c5d1SDavid du Colombier 	c->wds = wc;
268*3e12c5d1SDavid du Colombier 	return c;
269*3e12c5d1SDavid du Colombier 	}
270*3e12c5d1SDavid du Colombier 
271*3e12c5d1SDavid du Colombier  static Bigint *p5s;
272*3e12c5d1SDavid du Colombier 
273*3e12c5d1SDavid du Colombier  Bigint *
_pow5mult(Bigint * b,int k)274*3e12c5d1SDavid du Colombier _pow5mult(Bigint *b, int k)
275*3e12c5d1SDavid du Colombier {
276*3e12c5d1SDavid du Colombier 	Bigint *b1, *p5, *p51;
277*3e12c5d1SDavid du Colombier 	int i;
278*3e12c5d1SDavid du Colombier 	static int p05[3] = { 5, 25, 125 };
279*3e12c5d1SDavid du Colombier 
280*3e12c5d1SDavid du Colombier 	if (i = k & 3)
281*3e12c5d1SDavid du Colombier 		b = multadd(b, p05[i-1], 0);
282*3e12c5d1SDavid du Colombier 
283*3e12c5d1SDavid du Colombier 	if (!(k >>= 2))
284*3e12c5d1SDavid du Colombier 		return b;
285*3e12c5d1SDavid du Colombier 	if (!(p5 = p5s)) {
286*3e12c5d1SDavid du Colombier 		/* first time */
287*3e12c5d1SDavid du Colombier 		p5 = p5s = i2b(625);
288*3e12c5d1SDavid du Colombier 		p5->next = 0;
289*3e12c5d1SDavid du Colombier 		}
290*3e12c5d1SDavid du Colombier 	for(;;) {
291*3e12c5d1SDavid du Colombier 		if (k & 1) {
292*3e12c5d1SDavid du Colombier 			b1 = mult(b, p5);
293*3e12c5d1SDavid du Colombier 			Bfree(b);
294*3e12c5d1SDavid du Colombier 			b = b1;
295*3e12c5d1SDavid du Colombier 			}
296*3e12c5d1SDavid du Colombier 		if (!(k >>= 1))
297*3e12c5d1SDavid du Colombier 			break;
298*3e12c5d1SDavid du Colombier 		if (!(p51 = p5->next)) {
299*3e12c5d1SDavid du Colombier 			p51 = p5->next = mult(p5,p5);
300*3e12c5d1SDavid du Colombier 			p51->next = 0;
301*3e12c5d1SDavid du Colombier 			}
302*3e12c5d1SDavid du Colombier 		p5 = p51;
303*3e12c5d1SDavid du Colombier 		}
304*3e12c5d1SDavid du Colombier 	return b;
305*3e12c5d1SDavid du Colombier 	}
306*3e12c5d1SDavid du Colombier 
307*3e12c5d1SDavid du Colombier  Bigint *
_lshift(Bigint * b,int k)308*3e12c5d1SDavid du Colombier _lshift(Bigint *b, int k)
309*3e12c5d1SDavid du Colombier {
310*3e12c5d1SDavid du Colombier 	int i, k1, n, n1;
311*3e12c5d1SDavid du Colombier 	Bigint *b1;
312*3e12c5d1SDavid du Colombier 	unsigned long *x, *x1, *xe, z;
313*3e12c5d1SDavid du Colombier 
314*3e12c5d1SDavid du Colombier #ifdef Pack_32
315*3e12c5d1SDavid du Colombier 	n = k >> 5;
316*3e12c5d1SDavid du Colombier #else
317*3e12c5d1SDavid du Colombier 	n = k >> 4;
318*3e12c5d1SDavid du Colombier #endif
319*3e12c5d1SDavid du Colombier 	k1 = b->k;
320*3e12c5d1SDavid du Colombier 	n1 = n + b->wds + 1;
321*3e12c5d1SDavid du Colombier 	for(i = b->maxwds; n1 > i; i <<= 1)
322*3e12c5d1SDavid du Colombier 		k1++;
323*3e12c5d1SDavid du Colombier 	b1 = Balloc(k1);
324*3e12c5d1SDavid du Colombier 	x1 = b1->x;
325*3e12c5d1SDavid du Colombier 	for(i = 0; i < n; i++)
326*3e12c5d1SDavid du Colombier 		*x1++ = 0;
327*3e12c5d1SDavid du Colombier 	x = b->x;
328*3e12c5d1SDavid du Colombier 	xe = x + b->wds;
329*3e12c5d1SDavid du Colombier #ifdef Pack_32
330*3e12c5d1SDavid du Colombier 	if (k &= 0x1f) {
331*3e12c5d1SDavid du Colombier 		k1 = 32 - k;
332*3e12c5d1SDavid du Colombier 		z = 0;
333*3e12c5d1SDavid du Colombier 		do {
334*3e12c5d1SDavid du Colombier 			*x1++ = *x << k | z;
335*3e12c5d1SDavid du Colombier 			z = *x++ >> k1;
336*3e12c5d1SDavid du Colombier 			}
337*3e12c5d1SDavid du Colombier 			while(x < xe);
338*3e12c5d1SDavid du Colombier 		if (*x1 = z)
339*3e12c5d1SDavid du Colombier 			++n1;
340*3e12c5d1SDavid du Colombier 		}
341*3e12c5d1SDavid du Colombier #else
342*3e12c5d1SDavid du Colombier 	if (k &= 0xf) {
343*3e12c5d1SDavid du Colombier 		k1 = 16 - k;
344*3e12c5d1SDavid du Colombier 		z = 0;
345*3e12c5d1SDavid du Colombier 		do {
346*3e12c5d1SDavid du Colombier 			*x1++ = *x << k  & 0xffff | z;
347*3e12c5d1SDavid du Colombier 			z = *x++ >> k1;
348*3e12c5d1SDavid du Colombier 			}
349*3e12c5d1SDavid du Colombier 			while(x < xe);
350*3e12c5d1SDavid du Colombier 		if (*x1 = z)
351*3e12c5d1SDavid du Colombier 			++n1;
352*3e12c5d1SDavid du Colombier 		}
353*3e12c5d1SDavid du Colombier #endif
354*3e12c5d1SDavid du Colombier 	else do
355*3e12c5d1SDavid du Colombier 		*x1++ = *x++;
356*3e12c5d1SDavid du Colombier 		while(x < xe);
357*3e12c5d1SDavid du Colombier 	b1->wds = n1 - 1;
358*3e12c5d1SDavid du Colombier 	Bfree(b);
359*3e12c5d1SDavid du Colombier 	return b1;
360*3e12c5d1SDavid du Colombier 	}
361*3e12c5d1SDavid du Colombier 
362*3e12c5d1SDavid du Colombier  int
_cmp(Bigint * a,Bigint * b)363*3e12c5d1SDavid du Colombier _cmp(Bigint *a, Bigint *b)
364*3e12c5d1SDavid du Colombier {
365*3e12c5d1SDavid du Colombier 	unsigned long *xa, *xa0, *xb, *xb0;
366*3e12c5d1SDavid du Colombier 	int i, j;
367*3e12c5d1SDavid du Colombier 
368*3e12c5d1SDavid du Colombier 	i = a->wds;
369*3e12c5d1SDavid du Colombier 	j = b->wds;
370*3e12c5d1SDavid du Colombier #ifdef DEBUG
371*3e12c5d1SDavid du Colombier 	if (i > 1 && !a->x[i-1])
372*3e12c5d1SDavid du Colombier 		Bug("cmp called with a->x[a->wds-1] == 0");
373*3e12c5d1SDavid du Colombier 	if (j > 1 && !b->x[j-1])
374*3e12c5d1SDavid du Colombier 		Bug("cmp called with b->x[b->wds-1] == 0");
375*3e12c5d1SDavid du Colombier #endif
376*3e12c5d1SDavid du Colombier 	if (i -= j)
377*3e12c5d1SDavid du Colombier 		return i;
378*3e12c5d1SDavid du Colombier 	xa0 = a->x;
379*3e12c5d1SDavid du Colombier 	xa = xa0 + j;
380*3e12c5d1SDavid du Colombier 	xb0 = b->x;
381*3e12c5d1SDavid du Colombier 	xb = xb0 + j;
382*3e12c5d1SDavid du Colombier 	for(;;) {
383*3e12c5d1SDavid du Colombier 		if (*--xa != *--xb)
384*3e12c5d1SDavid du Colombier 			return *xa < *xb ? -1 : 1;
385*3e12c5d1SDavid du Colombier 		if (xa <= xa0)
386*3e12c5d1SDavid du Colombier 			break;
387*3e12c5d1SDavid du Colombier 		}
388*3e12c5d1SDavid du Colombier 	return 0;
389*3e12c5d1SDavid du Colombier 	}
390*3e12c5d1SDavid du Colombier 
391*3e12c5d1SDavid du Colombier  Bigint *
_diff(Bigint * a,Bigint * b)392*3e12c5d1SDavid du Colombier _diff(Bigint *a, Bigint *b)
393*3e12c5d1SDavid du Colombier {
394*3e12c5d1SDavid du Colombier 	Bigint *c;
395*3e12c5d1SDavid du Colombier 	int i, wa, wb;
396*3e12c5d1SDavid du Colombier 	long borrow, y;	/* We need signed shifts here. */
397*3e12c5d1SDavid du Colombier 	unsigned long *xa, *xae, *xb, *xbe, *xc;
398*3e12c5d1SDavid du Colombier #ifdef Pack_32
399*3e12c5d1SDavid du Colombier 	long z;
400*3e12c5d1SDavid du Colombier #endif
401*3e12c5d1SDavid du Colombier 
402*3e12c5d1SDavid du Colombier 	i = cmp(a,b);
403*3e12c5d1SDavid du Colombier 	if (!i) {
404*3e12c5d1SDavid du Colombier 		c = Balloc(0);
405*3e12c5d1SDavid du Colombier 		c->wds = 1;
406*3e12c5d1SDavid du Colombier 		c->x[0] = 0;
407*3e12c5d1SDavid du Colombier 		return c;
408*3e12c5d1SDavid du Colombier 		}
409*3e12c5d1SDavid du Colombier 	if (i < 0) {
410*3e12c5d1SDavid du Colombier 		c = a;
411*3e12c5d1SDavid du Colombier 		a = b;
412*3e12c5d1SDavid du Colombier 		b = c;
413*3e12c5d1SDavid du Colombier 		i = 1;
414*3e12c5d1SDavid du Colombier 		}
415*3e12c5d1SDavid du Colombier 	else
416*3e12c5d1SDavid du Colombier 		i = 0;
417*3e12c5d1SDavid du Colombier 	c = Balloc(a->k);
418*3e12c5d1SDavid du Colombier 	c->sign = i;
419*3e12c5d1SDavid du Colombier 	wa = a->wds;
420*3e12c5d1SDavid du Colombier 	xa = a->x;
421*3e12c5d1SDavid du Colombier 	xae = xa + wa;
422*3e12c5d1SDavid du Colombier 	wb = b->wds;
423*3e12c5d1SDavid du Colombier 	xb = b->x;
424*3e12c5d1SDavid du Colombier 	xbe = xb + wb;
425*3e12c5d1SDavid du Colombier 	xc = c->x;
426*3e12c5d1SDavid du Colombier 	borrow = 0;
427*3e12c5d1SDavid du Colombier #ifdef Pack_32
428*3e12c5d1SDavid du Colombier 	do {
429*3e12c5d1SDavid du Colombier 		y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
430*3e12c5d1SDavid du Colombier 		borrow = y >> 16;
431*3e12c5d1SDavid du Colombier 		Sign_Extend(borrow, y);
432*3e12c5d1SDavid du Colombier 		z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
433*3e12c5d1SDavid du Colombier 		borrow = z >> 16;
434*3e12c5d1SDavid du Colombier 		Sign_Extend(borrow, z);
435*3e12c5d1SDavid du Colombier 		Storeinc(xc, z, y);
436*3e12c5d1SDavid du Colombier 		}
437*3e12c5d1SDavid du Colombier 		while(xb < xbe);
438*3e12c5d1SDavid du Colombier 	while(xa < xae) {
439*3e12c5d1SDavid du Colombier 		y = (*xa & 0xffff) + borrow;
440*3e12c5d1SDavid du Colombier 		borrow = y >> 16;
441*3e12c5d1SDavid du Colombier 		Sign_Extend(borrow, y);
442*3e12c5d1SDavid du Colombier 		z = (*xa++ >> 16) + borrow;
443*3e12c5d1SDavid du Colombier 		borrow = z >> 16;
444*3e12c5d1SDavid du Colombier 		Sign_Extend(borrow, z);
445*3e12c5d1SDavid du Colombier 		Storeinc(xc, z, y);
446*3e12c5d1SDavid du Colombier 		}
447*3e12c5d1SDavid du Colombier #else
448*3e12c5d1SDavid du Colombier 	do {
449*3e12c5d1SDavid du Colombier 		y = *xa++ - *xb++ + borrow;
450*3e12c5d1SDavid du Colombier 		borrow = y >> 16;
451*3e12c5d1SDavid du Colombier 		Sign_Extend(borrow, y);
452*3e12c5d1SDavid du Colombier 		*xc++ = y & 0xffff;
453*3e12c5d1SDavid du Colombier 		}
454*3e12c5d1SDavid du Colombier 		while(xb < xbe);
455*3e12c5d1SDavid du Colombier 	while(xa < xae) {
456*3e12c5d1SDavid du Colombier 		y = *xa++ + borrow;
457*3e12c5d1SDavid du Colombier 		borrow = y >> 16;
458*3e12c5d1SDavid du Colombier 		Sign_Extend(borrow, y);
459*3e12c5d1SDavid du Colombier 		*xc++ = y & 0xffff;
460*3e12c5d1SDavid du Colombier 		}
461*3e12c5d1SDavid du Colombier #endif
462*3e12c5d1SDavid du Colombier 	while(!*--xc)
463*3e12c5d1SDavid du Colombier 		wa--;
464*3e12c5d1SDavid du Colombier 	c->wds = wa;
465*3e12c5d1SDavid du Colombier 	return c;
466*3e12c5d1SDavid du Colombier 	}
467*3e12c5d1SDavid du Colombier 
468*3e12c5d1SDavid du Colombier  Bigint *
_d2b(double darg,int * e,int * bits)469*3e12c5d1SDavid du Colombier _d2b(double darg, int *e, int *bits)
470*3e12c5d1SDavid du Colombier {
471*3e12c5d1SDavid du Colombier 	Bigint *b;
472*3e12c5d1SDavid du Colombier 	int de, i, k;
473*3e12c5d1SDavid du Colombier 	unsigned long *x, y, z;
474*3e12c5d1SDavid du Colombier 	Dul d;
475*3e12c5d1SDavid du Colombier #ifdef VAX
476*3e12c5d1SDavid du Colombier 	unsigned long d0, d1;
477*3e12c5d1SDavid du Colombier 	d.d = darg;
478*3e12c5d1SDavid du Colombier 	d0 = word0(d) >> 16 | word0(d) << 16;
479*3e12c5d1SDavid du Colombier 	d1 = word1(d) >> 16 | word1(d) << 16;
480*3e12c5d1SDavid du Colombier #else
481*3e12c5d1SDavid du Colombier 	d.d = darg;
482*3e12c5d1SDavid du Colombier #define d0 word0(d)
483*3e12c5d1SDavid du Colombier #define d1 word1(d)
484*3e12c5d1SDavid du Colombier #endif
485*3e12c5d1SDavid du Colombier 
486*3e12c5d1SDavid du Colombier #ifdef Pack_32
487*3e12c5d1SDavid du Colombier 	b = Balloc(1);
488*3e12c5d1SDavid du Colombier #else
489*3e12c5d1SDavid du Colombier 	b = Balloc(2);
490*3e12c5d1SDavid du Colombier #endif
491*3e12c5d1SDavid du Colombier 	x = b->x;
492*3e12c5d1SDavid du Colombier 
493*3e12c5d1SDavid du Colombier 	z = d0 & Frac_mask;
494*3e12c5d1SDavid du Colombier 	d0 &= 0x7fffffff;	/* clear sign bit, which we ignore */
495*3e12c5d1SDavid du Colombier #ifdef Sudden_Underflow
496*3e12c5d1SDavid du Colombier 	de = (int)(d0 >> Exp_shift);
497*3e12c5d1SDavid du Colombier #ifndef IBM
498*3e12c5d1SDavid du Colombier 	z |= Exp_msk11;
499*3e12c5d1SDavid du Colombier #endif
500*3e12c5d1SDavid du Colombier #else
501*3e12c5d1SDavid du Colombier 	if (de = (int)(d0 >> Exp_shift))
502*3e12c5d1SDavid du Colombier 		z |= Exp_msk1;
503*3e12c5d1SDavid du Colombier #endif
504*3e12c5d1SDavid du Colombier #ifdef Pack_32
505*3e12c5d1SDavid du Colombier 	if (y = d1) {
506*3e12c5d1SDavid du Colombier 		if (k = lo0bits(&y)) {
507*3e12c5d1SDavid du Colombier 			x[0] = y | z << 32 - k;
508*3e12c5d1SDavid du Colombier 			z >>= k;
509*3e12c5d1SDavid du Colombier 			}
510*3e12c5d1SDavid du Colombier 		else
511*3e12c5d1SDavid du Colombier 			x[0] = y;
512*3e12c5d1SDavid du Colombier 		i = b->wds = (x[1] = z) ? 2 : 1;
513*3e12c5d1SDavid du Colombier 		}
514*3e12c5d1SDavid du Colombier 	else {
515*3e12c5d1SDavid du Colombier #ifdef DEBUG
516*3e12c5d1SDavid du Colombier 		if (!z)
517*3e12c5d1SDavid du Colombier 			Bug("Zero passed to d2b");
518*3e12c5d1SDavid du Colombier #endif
519*3e12c5d1SDavid du Colombier 		k = lo0bits(&z);
520*3e12c5d1SDavid du Colombier 		x[0] = z;
521*3e12c5d1SDavid du Colombier 		i = b->wds = 1;
522*3e12c5d1SDavid du Colombier 		k += 32;
523*3e12c5d1SDavid du Colombier 		}
524*3e12c5d1SDavid du Colombier #else
525*3e12c5d1SDavid du Colombier 	if (y = d1) {
526*3e12c5d1SDavid du Colombier 		if (k = lo0bits(&y))
527*3e12c5d1SDavid du Colombier 			if (k >= 16) {
528*3e12c5d1SDavid du Colombier 				x[0] = y | z << 32 - k & 0xffff;
529*3e12c5d1SDavid du Colombier 				x[1] = z >> k - 16 & 0xffff;
530*3e12c5d1SDavid du Colombier 				x[2] = z >> k;
531*3e12c5d1SDavid du Colombier 				i = 2;
532*3e12c5d1SDavid du Colombier 				}
533*3e12c5d1SDavid du Colombier 			else {
534*3e12c5d1SDavid du Colombier 				x[0] = y & 0xffff;
535*3e12c5d1SDavid du Colombier 				x[1] = y >> 16 | z << 16 - k & 0xffff;
536*3e12c5d1SDavid du Colombier 				x[2] = z >> k & 0xffff;
537*3e12c5d1SDavid du Colombier 				x[3] = z >> k+16;
538*3e12c5d1SDavid du Colombier 				i = 3;
539*3e12c5d1SDavid du Colombier 				}
540*3e12c5d1SDavid du Colombier 		else {
541*3e12c5d1SDavid du Colombier 			x[0] = y & 0xffff;
542*3e12c5d1SDavid du Colombier 			x[1] = y >> 16;
543*3e12c5d1SDavid du Colombier 			x[2] = z & 0xffff;
544*3e12c5d1SDavid du Colombier 			x[3] = z >> 16;
545*3e12c5d1SDavid du Colombier 			i = 3;
546*3e12c5d1SDavid du Colombier 			}
547*3e12c5d1SDavid du Colombier 		}
548*3e12c5d1SDavid du Colombier 	else {
549*3e12c5d1SDavid du Colombier #ifdef DEBUG
550*3e12c5d1SDavid du Colombier 		if (!z)
551*3e12c5d1SDavid du Colombier 			Bug("Zero passed to d2b");
552*3e12c5d1SDavid du Colombier #endif
553*3e12c5d1SDavid du Colombier 		k = lo0bits(&z);
554*3e12c5d1SDavid du Colombier 		if (k >= 16) {
555*3e12c5d1SDavid du Colombier 			x[0] = z;
556*3e12c5d1SDavid du Colombier 			i = 0;
557*3e12c5d1SDavid du Colombier 			}
558*3e12c5d1SDavid du Colombier 		else {
559*3e12c5d1SDavid du Colombier 			x[0] = z & 0xffff;
560*3e12c5d1SDavid du Colombier 			x[1] = z >> 16;
561*3e12c5d1SDavid du Colombier 			i = 1;
562*3e12c5d1SDavid du Colombier 			}
563*3e12c5d1SDavid du Colombier 		k += 32;
564*3e12c5d1SDavid du Colombier 		}
565*3e12c5d1SDavid du Colombier 	while(!x[i])
566*3e12c5d1SDavid du Colombier 		--i;
567*3e12c5d1SDavid du Colombier 	b->wds = i + 1;
568*3e12c5d1SDavid du Colombier #endif
569*3e12c5d1SDavid du Colombier #ifndef Sudden_Underflow
570*3e12c5d1SDavid du Colombier 	if (de) {
571*3e12c5d1SDavid du Colombier #endif
572*3e12c5d1SDavid du Colombier #ifdef IBM
573*3e12c5d1SDavid du Colombier 		*e = (de - Bias - (P-1) << 2) + k;
574*3e12c5d1SDavid du Colombier 		*bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
575*3e12c5d1SDavid du Colombier #else
576*3e12c5d1SDavid du Colombier 		*e = de - Bias - (P-1) + k;
577*3e12c5d1SDavid du Colombier 		*bits = P - k;
578*3e12c5d1SDavid du Colombier #endif
579*3e12c5d1SDavid du Colombier #ifndef Sudden_Underflow
580*3e12c5d1SDavid du Colombier 		}
581*3e12c5d1SDavid du Colombier 	else {
582*3e12c5d1SDavid du Colombier 		*e = de - Bias - (P-1) + 1 + k;
583*3e12c5d1SDavid du Colombier #ifdef Pack_32
584*3e12c5d1SDavid du Colombier 		*bits = 32*i - hi0bits(x[i-1]);
585*3e12c5d1SDavid du Colombier #else
586*3e12c5d1SDavid du Colombier 		*bits = (i+2)*16 - hi0bits(x[i]);
587*3e12c5d1SDavid du Colombier #endif
588*3e12c5d1SDavid du Colombier 		}
589*3e12c5d1SDavid du Colombier #endif
590*3e12c5d1SDavid du Colombier 	return b;
591*3e12c5d1SDavid du Colombier 	}
592*3e12c5d1SDavid du Colombier #undef d0
593*3e12c5d1SDavid du Colombier #undef d1
594