xref: /freebsd/contrib/gdtoa/misc.c (revision cc36ccd13b36b705dfb09d90e8de63e49734f8d4)
1cc36ccd1SDavid Schultz /****************************************************************
2cc36ccd1SDavid Schultz 
3cc36ccd1SDavid Schultz The author of this software is David M. Gay.
4cc36ccd1SDavid Schultz 
5cc36ccd1SDavid Schultz Copyright (C) 1998, 1999 by Lucent Technologies
6cc36ccd1SDavid Schultz All Rights Reserved
7cc36ccd1SDavid Schultz 
8cc36ccd1SDavid Schultz Permission to use, copy, modify, and distribute this software and
9cc36ccd1SDavid Schultz its documentation for any purpose and without fee is hereby
10cc36ccd1SDavid Schultz granted, provided that the above copyright notice appear in all
11cc36ccd1SDavid Schultz copies and that both that the copyright notice and this
12cc36ccd1SDavid Schultz permission notice and warranty disclaimer appear in supporting
13cc36ccd1SDavid Schultz documentation, and that the name of Lucent or any of its entities
14cc36ccd1SDavid Schultz not be used in advertising or publicity pertaining to
15cc36ccd1SDavid Schultz distribution of the software without specific, written prior
16cc36ccd1SDavid Schultz permission.
17cc36ccd1SDavid Schultz 
18cc36ccd1SDavid Schultz LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19cc36ccd1SDavid Schultz INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20cc36ccd1SDavid Schultz IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21cc36ccd1SDavid Schultz SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22cc36ccd1SDavid Schultz WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23cc36ccd1SDavid Schultz IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24cc36ccd1SDavid Schultz ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25cc36ccd1SDavid Schultz THIS SOFTWARE.
26cc36ccd1SDavid Schultz 
27cc36ccd1SDavid Schultz ****************************************************************/
28cc36ccd1SDavid Schultz 
29cc36ccd1SDavid Schultz /* Please send bug reports to
30cc36ccd1SDavid Schultz 	David M. Gay
31cc36ccd1SDavid Schultz 	Bell Laboratories, Room 2C-463
32cc36ccd1SDavid Schultz 	600 Mountain Avenue
33cc36ccd1SDavid Schultz 	Murray Hill, NJ 07974-0636
34cc36ccd1SDavid Schultz 	U.S.A.
35cc36ccd1SDavid Schultz 	dmg@bell-labs.com
36cc36ccd1SDavid Schultz  */
37cc36ccd1SDavid Schultz 
38cc36ccd1SDavid Schultz #include "gdtoaimp.h"
39cc36ccd1SDavid Schultz 
40cc36ccd1SDavid Schultz  static Bigint *freelist[Kmax+1];
41cc36ccd1SDavid Schultz #ifndef Omit_Private_Memory
42cc36ccd1SDavid Schultz #ifndef PRIVATE_MEM
43cc36ccd1SDavid Schultz #define PRIVATE_MEM 2304
44cc36ccd1SDavid Schultz #endif
45cc36ccd1SDavid Schultz #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
46cc36ccd1SDavid Schultz static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
47cc36ccd1SDavid Schultz #endif
48cc36ccd1SDavid Schultz 
49cc36ccd1SDavid Schultz  Bigint *
50cc36ccd1SDavid Schultz Balloc
51cc36ccd1SDavid Schultz #ifdef KR_headers
52cc36ccd1SDavid Schultz 	(k) int k;
53cc36ccd1SDavid Schultz #else
54cc36ccd1SDavid Schultz 	(int k)
55cc36ccd1SDavid Schultz #endif
56cc36ccd1SDavid Schultz {
57cc36ccd1SDavid Schultz 	int x;
58cc36ccd1SDavid Schultz 	Bigint *rv;
59cc36ccd1SDavid Schultz #ifndef Omit_Private_Memory
60cc36ccd1SDavid Schultz 	unsigned int len;
61cc36ccd1SDavid Schultz #endif
62cc36ccd1SDavid Schultz 
63cc36ccd1SDavid Schultz 	ACQUIRE_DTOA_LOCK(0);
64cc36ccd1SDavid Schultz 	if ( (rv = freelist[k]) !=0) {
65cc36ccd1SDavid Schultz 		freelist[k] = rv->next;
66cc36ccd1SDavid Schultz 		}
67cc36ccd1SDavid Schultz 	else {
68cc36ccd1SDavid Schultz 		x = 1 << k;
69cc36ccd1SDavid Schultz #ifdef Omit_Private_Memory
70cc36ccd1SDavid Schultz 		rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
71cc36ccd1SDavid Schultz #else
72cc36ccd1SDavid Schultz 		len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
73cc36ccd1SDavid Schultz 			/sizeof(double);
74cc36ccd1SDavid Schultz 		if (pmem_next - private_mem + len <= PRIVATE_mem) {
75cc36ccd1SDavid Schultz 			rv = (Bigint*)pmem_next;
76cc36ccd1SDavid Schultz 			pmem_next += len;
77cc36ccd1SDavid Schultz 			}
78cc36ccd1SDavid Schultz 		else
79cc36ccd1SDavid Schultz 			rv = (Bigint*)MALLOC(len*sizeof(double));
80cc36ccd1SDavid Schultz #endif
81cc36ccd1SDavid Schultz 		rv->k = k;
82cc36ccd1SDavid Schultz 		rv->maxwds = x;
83cc36ccd1SDavid Schultz 		}
84cc36ccd1SDavid Schultz 	FREE_DTOA_LOCK(0);
85cc36ccd1SDavid Schultz 	rv->sign = rv->wds = 0;
86cc36ccd1SDavid Schultz 	return rv;
87cc36ccd1SDavid Schultz 	}
88cc36ccd1SDavid Schultz 
89cc36ccd1SDavid Schultz  void
90cc36ccd1SDavid Schultz Bfree
91cc36ccd1SDavid Schultz #ifdef KR_headers
92cc36ccd1SDavid Schultz 	(v) Bigint *v;
93cc36ccd1SDavid Schultz #else
94cc36ccd1SDavid Schultz 	(Bigint *v)
95cc36ccd1SDavid Schultz #endif
96cc36ccd1SDavid Schultz {
97cc36ccd1SDavid Schultz 	if (v) {
98cc36ccd1SDavid Schultz 		ACQUIRE_DTOA_LOCK(0);
99cc36ccd1SDavid Schultz 		v->next = freelist[v->k];
100cc36ccd1SDavid Schultz 		freelist[v->k] = v;
101cc36ccd1SDavid Schultz 		FREE_DTOA_LOCK(0);
102cc36ccd1SDavid Schultz 		}
103cc36ccd1SDavid Schultz 	}
104cc36ccd1SDavid Schultz 
105cc36ccd1SDavid Schultz  int
106cc36ccd1SDavid Schultz lo0bits
107cc36ccd1SDavid Schultz #ifdef KR_headers
108cc36ccd1SDavid Schultz 	(y) ULong *y;
109cc36ccd1SDavid Schultz #else
110cc36ccd1SDavid Schultz 	(ULong *y)
111cc36ccd1SDavid Schultz #endif
112cc36ccd1SDavid Schultz {
113cc36ccd1SDavid Schultz 	register int k;
114cc36ccd1SDavid Schultz 	register ULong x = *y;
115cc36ccd1SDavid Schultz 
116cc36ccd1SDavid Schultz 	if (x & 7) {
117cc36ccd1SDavid Schultz 		if (x & 1)
118cc36ccd1SDavid Schultz 			return 0;
119cc36ccd1SDavid Schultz 		if (x & 2) {
120cc36ccd1SDavid Schultz 			*y = x >> 1;
121cc36ccd1SDavid Schultz 			return 1;
122cc36ccd1SDavid Schultz 			}
123cc36ccd1SDavid Schultz 		*y = x >> 2;
124cc36ccd1SDavid Schultz 		return 2;
125cc36ccd1SDavid Schultz 		}
126cc36ccd1SDavid Schultz 	k = 0;
127cc36ccd1SDavid Schultz 	if (!(x & 0xffff)) {
128cc36ccd1SDavid Schultz 		k = 16;
129cc36ccd1SDavid Schultz 		x >>= 16;
130cc36ccd1SDavid Schultz 		}
131cc36ccd1SDavid Schultz 	if (!(x & 0xff)) {
132cc36ccd1SDavid Schultz 		k += 8;
133cc36ccd1SDavid Schultz 		x >>= 8;
134cc36ccd1SDavid Schultz 		}
135cc36ccd1SDavid Schultz 	if (!(x & 0xf)) {
136cc36ccd1SDavid Schultz 		k += 4;
137cc36ccd1SDavid Schultz 		x >>= 4;
138cc36ccd1SDavid Schultz 		}
139cc36ccd1SDavid Schultz 	if (!(x & 0x3)) {
140cc36ccd1SDavid Schultz 		k += 2;
141cc36ccd1SDavid Schultz 		x >>= 2;
142cc36ccd1SDavid Schultz 		}
143cc36ccd1SDavid Schultz 	if (!(x & 1)) {
144cc36ccd1SDavid Schultz 		k++;
145cc36ccd1SDavid Schultz 		x >>= 1;
146cc36ccd1SDavid Schultz 		if (!x & 1)
147cc36ccd1SDavid Schultz 			return 32;
148cc36ccd1SDavid Schultz 		}
149cc36ccd1SDavid Schultz 	*y = x;
150cc36ccd1SDavid Schultz 	return k;
151cc36ccd1SDavid Schultz 	}
152cc36ccd1SDavid Schultz 
153cc36ccd1SDavid Schultz  Bigint *
154cc36ccd1SDavid Schultz multadd
155cc36ccd1SDavid Schultz #ifdef KR_headers
156cc36ccd1SDavid Schultz 	(b, m, a) Bigint *b; int m, a;
157cc36ccd1SDavid Schultz #else
158cc36ccd1SDavid Schultz 	(Bigint *b, int m, int a)	/* multiply by m and add a */
159cc36ccd1SDavid Schultz #endif
160cc36ccd1SDavid Schultz {
161cc36ccd1SDavid Schultz 	int i, wds;
162cc36ccd1SDavid Schultz #ifdef ULLong
163cc36ccd1SDavid Schultz 	ULong *x;
164cc36ccd1SDavid Schultz 	ULLong carry, y;
165cc36ccd1SDavid Schultz #else
166cc36ccd1SDavid Schultz 	ULong carry, *x, y;
167cc36ccd1SDavid Schultz #ifdef Pack_32
168cc36ccd1SDavid Schultz 	ULong xi, z;
169cc36ccd1SDavid Schultz #endif
170cc36ccd1SDavid Schultz #endif
171cc36ccd1SDavid Schultz 	Bigint *b1;
172cc36ccd1SDavid Schultz 
173cc36ccd1SDavid Schultz 	wds = b->wds;
174cc36ccd1SDavid Schultz 	x = b->x;
175cc36ccd1SDavid Schultz 	i = 0;
176cc36ccd1SDavid Schultz 	carry = a;
177cc36ccd1SDavid Schultz 	do {
178cc36ccd1SDavid Schultz #ifdef ULLong
179cc36ccd1SDavid Schultz 		y = *x * (ULLong)m + carry;
180cc36ccd1SDavid Schultz 		carry = y >> 32;
181cc36ccd1SDavid Schultz 		*x++ = y & 0xffffffffUL;
182cc36ccd1SDavid Schultz #else
183cc36ccd1SDavid Schultz #ifdef Pack_32
184cc36ccd1SDavid Schultz 		xi = *x;
185cc36ccd1SDavid Schultz 		y = (xi & 0xffff) * m + carry;
186cc36ccd1SDavid Schultz 		z = (xi >> 16) * m + (y >> 16);
187cc36ccd1SDavid Schultz 		carry = z >> 16;
188cc36ccd1SDavid Schultz 		*x++ = (z << 16) + (y & 0xffff);
189cc36ccd1SDavid Schultz #else
190cc36ccd1SDavid Schultz 		y = *x * m + carry;
191cc36ccd1SDavid Schultz 		carry = y >> 16;
192cc36ccd1SDavid Schultz 		*x++ = y & 0xffff;
193cc36ccd1SDavid Schultz #endif
194cc36ccd1SDavid Schultz #endif
195cc36ccd1SDavid Schultz 		}
196cc36ccd1SDavid Schultz 		while(++i < wds);
197cc36ccd1SDavid Schultz 	if (carry) {
198cc36ccd1SDavid Schultz 		if (wds >= b->maxwds) {
199cc36ccd1SDavid Schultz 			b1 = Balloc(b->k+1);
200cc36ccd1SDavid Schultz 			Bcopy(b1, b);
201cc36ccd1SDavid Schultz 			Bfree(b);
202cc36ccd1SDavid Schultz 			b = b1;
203cc36ccd1SDavid Schultz 			}
204cc36ccd1SDavid Schultz 		b->x[wds++] = carry;
205cc36ccd1SDavid Schultz 		b->wds = wds;
206cc36ccd1SDavid Schultz 		}
207cc36ccd1SDavid Schultz 	return b;
208cc36ccd1SDavid Schultz 	}
209cc36ccd1SDavid Schultz 
210cc36ccd1SDavid Schultz  int
211cc36ccd1SDavid Schultz hi0bits
212cc36ccd1SDavid Schultz #ifdef KR_headers
213cc36ccd1SDavid Schultz 	(x) register ULong x;
214cc36ccd1SDavid Schultz #else
215cc36ccd1SDavid Schultz 	(register ULong x)
216cc36ccd1SDavid Schultz #endif
217cc36ccd1SDavid Schultz {
218cc36ccd1SDavid Schultz 	register int k = 0;
219cc36ccd1SDavid Schultz 
220cc36ccd1SDavid Schultz 	if (!(x & 0xffff0000)) {
221cc36ccd1SDavid Schultz 		k = 16;
222cc36ccd1SDavid Schultz 		x <<= 16;
223cc36ccd1SDavid Schultz 		}
224cc36ccd1SDavid Schultz 	if (!(x & 0xff000000)) {
225cc36ccd1SDavid Schultz 		k += 8;
226cc36ccd1SDavid Schultz 		x <<= 8;
227cc36ccd1SDavid Schultz 		}
228cc36ccd1SDavid Schultz 	if (!(x & 0xf0000000)) {
229cc36ccd1SDavid Schultz 		k += 4;
230cc36ccd1SDavid Schultz 		x <<= 4;
231cc36ccd1SDavid Schultz 		}
232cc36ccd1SDavid Schultz 	if (!(x & 0xc0000000)) {
233cc36ccd1SDavid Schultz 		k += 2;
234cc36ccd1SDavid Schultz 		x <<= 2;
235cc36ccd1SDavid Schultz 		}
236cc36ccd1SDavid Schultz 	if (!(x & 0x80000000)) {
237cc36ccd1SDavid Schultz 		k++;
238cc36ccd1SDavid Schultz 		if (!(x & 0x40000000))
239cc36ccd1SDavid Schultz 			return 32;
240cc36ccd1SDavid Schultz 		}
241cc36ccd1SDavid Schultz 	return k;
242cc36ccd1SDavid Schultz 	}
243cc36ccd1SDavid Schultz 
244cc36ccd1SDavid Schultz  Bigint *
245cc36ccd1SDavid Schultz i2b
246cc36ccd1SDavid Schultz #ifdef KR_headers
247cc36ccd1SDavid Schultz 	(i) int i;
248cc36ccd1SDavid Schultz #else
249cc36ccd1SDavid Schultz 	(int i)
250cc36ccd1SDavid Schultz #endif
251cc36ccd1SDavid Schultz {
252cc36ccd1SDavid Schultz 	Bigint *b;
253cc36ccd1SDavid Schultz 
254cc36ccd1SDavid Schultz 	b = Balloc(1);
255cc36ccd1SDavid Schultz 	b->x[0] = i;
256cc36ccd1SDavid Schultz 	b->wds = 1;
257cc36ccd1SDavid Schultz 	return b;
258cc36ccd1SDavid Schultz 	}
259cc36ccd1SDavid Schultz 
260cc36ccd1SDavid Schultz  Bigint *
261cc36ccd1SDavid Schultz mult
262cc36ccd1SDavid Schultz #ifdef KR_headers
263cc36ccd1SDavid Schultz 	(a, b) Bigint *a, *b;
264cc36ccd1SDavid Schultz #else
265cc36ccd1SDavid Schultz 	(Bigint *a, Bigint *b)
266cc36ccd1SDavid Schultz #endif
267cc36ccd1SDavid Schultz {
268cc36ccd1SDavid Schultz 	Bigint *c;
269cc36ccd1SDavid Schultz 	int k, wa, wb, wc;
270cc36ccd1SDavid Schultz 	ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
271cc36ccd1SDavid Schultz 	ULong y;
272cc36ccd1SDavid Schultz #ifdef ULLong
273cc36ccd1SDavid Schultz 	ULLong carry, z;
274cc36ccd1SDavid Schultz #else
275cc36ccd1SDavid Schultz 	ULong carry, z;
276cc36ccd1SDavid Schultz #ifdef Pack_32
277cc36ccd1SDavid Schultz 	ULong z2;
278cc36ccd1SDavid Schultz #endif
279cc36ccd1SDavid Schultz #endif
280cc36ccd1SDavid Schultz 
281cc36ccd1SDavid Schultz 	if (a->wds < b->wds) {
282cc36ccd1SDavid Schultz 		c = a;
283cc36ccd1SDavid Schultz 		a = b;
284cc36ccd1SDavid Schultz 		b = c;
285cc36ccd1SDavid Schultz 		}
286cc36ccd1SDavid Schultz 	k = a->k;
287cc36ccd1SDavid Schultz 	wa = a->wds;
288cc36ccd1SDavid Schultz 	wb = b->wds;
289cc36ccd1SDavid Schultz 	wc = wa + wb;
290cc36ccd1SDavid Schultz 	if (wc > a->maxwds)
291cc36ccd1SDavid Schultz 		k++;
292cc36ccd1SDavid Schultz 	c = Balloc(k);
293cc36ccd1SDavid Schultz 	for(x = c->x, xa = x + wc; x < xa; x++)
294cc36ccd1SDavid Schultz 		*x = 0;
295cc36ccd1SDavid Schultz 	xa = a->x;
296cc36ccd1SDavid Schultz 	xae = xa + wa;
297cc36ccd1SDavid Schultz 	xb = b->x;
298cc36ccd1SDavid Schultz 	xbe = xb + wb;
299cc36ccd1SDavid Schultz 	xc0 = c->x;
300cc36ccd1SDavid Schultz #ifdef ULLong
301cc36ccd1SDavid Schultz 	for(; xb < xbe; xc0++) {
302cc36ccd1SDavid Schultz 		if ( (y = *xb++) !=0) {
303cc36ccd1SDavid Schultz 			x = xa;
304cc36ccd1SDavid Schultz 			xc = xc0;
305cc36ccd1SDavid Schultz 			carry = 0;
306cc36ccd1SDavid Schultz 			do {
307cc36ccd1SDavid Schultz 				z = *x++ * (ULLong)y + *xc + carry;
308cc36ccd1SDavid Schultz 				carry = z >> 32;
309cc36ccd1SDavid Schultz 				*xc++ = z & 0xffffffffUL;
310cc36ccd1SDavid Schultz 				}
311cc36ccd1SDavid Schultz 				while(x < xae);
312cc36ccd1SDavid Schultz 			*xc = carry;
313cc36ccd1SDavid Schultz 			}
314cc36ccd1SDavid Schultz 		}
315cc36ccd1SDavid Schultz #else
316cc36ccd1SDavid Schultz #ifdef Pack_32
317cc36ccd1SDavid Schultz 	for(; xb < xbe; xb++, xc0++) {
318cc36ccd1SDavid Schultz 		if ( (y = *xb & 0xffff) !=0) {
319cc36ccd1SDavid Schultz 			x = xa;
320cc36ccd1SDavid Schultz 			xc = xc0;
321cc36ccd1SDavid Schultz 			carry = 0;
322cc36ccd1SDavid Schultz 			do {
323cc36ccd1SDavid Schultz 				z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
324cc36ccd1SDavid Schultz 				carry = z >> 16;
325cc36ccd1SDavid Schultz 				z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
326cc36ccd1SDavid Schultz 				carry = z2 >> 16;
327cc36ccd1SDavid Schultz 				Storeinc(xc, z2, z);
328cc36ccd1SDavid Schultz 				}
329cc36ccd1SDavid Schultz 				while(x < xae);
330cc36ccd1SDavid Schultz 			*xc = carry;
331cc36ccd1SDavid Schultz 			}
332cc36ccd1SDavid Schultz 		if ( (y = *xb >> 16) !=0) {
333cc36ccd1SDavid Schultz 			x = xa;
334cc36ccd1SDavid Schultz 			xc = xc0;
335cc36ccd1SDavid Schultz 			carry = 0;
336cc36ccd1SDavid Schultz 			z2 = *xc;
337cc36ccd1SDavid Schultz 			do {
338cc36ccd1SDavid Schultz 				z = (*x & 0xffff) * y + (*xc >> 16) + carry;
339cc36ccd1SDavid Schultz 				carry = z >> 16;
340cc36ccd1SDavid Schultz 				Storeinc(xc, z, z2);
341cc36ccd1SDavid Schultz 				z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
342cc36ccd1SDavid Schultz 				carry = z2 >> 16;
343cc36ccd1SDavid Schultz 				}
344cc36ccd1SDavid Schultz 				while(x < xae);
345cc36ccd1SDavid Schultz 			*xc = z2;
346cc36ccd1SDavid Schultz 			}
347cc36ccd1SDavid Schultz 		}
348cc36ccd1SDavid Schultz #else
349cc36ccd1SDavid Schultz 	for(; xb < xbe; xc0++) {
350cc36ccd1SDavid Schultz 		if ( (y = *xb++) !=0) {
351cc36ccd1SDavid Schultz 			x = xa;
352cc36ccd1SDavid Schultz 			xc = xc0;
353cc36ccd1SDavid Schultz 			carry = 0;
354cc36ccd1SDavid Schultz 			do {
355cc36ccd1SDavid Schultz 				z = *x++ * y + *xc + carry;
356cc36ccd1SDavid Schultz 				carry = z >> 16;
357cc36ccd1SDavid Schultz 				*xc++ = z & 0xffff;
358cc36ccd1SDavid Schultz 				}
359cc36ccd1SDavid Schultz 				while(x < xae);
360cc36ccd1SDavid Schultz 			*xc = carry;
361cc36ccd1SDavid Schultz 			}
362cc36ccd1SDavid Schultz 		}
363cc36ccd1SDavid Schultz #endif
364cc36ccd1SDavid Schultz #endif
365cc36ccd1SDavid Schultz 	for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
366cc36ccd1SDavid Schultz 	c->wds = wc;
367cc36ccd1SDavid Schultz 	return c;
368cc36ccd1SDavid Schultz 	}
369cc36ccd1SDavid Schultz 
370cc36ccd1SDavid Schultz  static Bigint *p5s;
371cc36ccd1SDavid Schultz 
372cc36ccd1SDavid Schultz  Bigint *
373cc36ccd1SDavid Schultz pow5mult
374cc36ccd1SDavid Schultz #ifdef KR_headers
375cc36ccd1SDavid Schultz 	(b, k) Bigint *b; int k;
376cc36ccd1SDavid Schultz #else
377cc36ccd1SDavid Schultz 	(Bigint *b, int k)
378cc36ccd1SDavid Schultz #endif
379cc36ccd1SDavid Schultz {
380cc36ccd1SDavid Schultz 	Bigint *b1, *p5, *p51;
381cc36ccd1SDavid Schultz 	int i;
382cc36ccd1SDavid Schultz 	static int p05[3] = { 5, 25, 125 };
383cc36ccd1SDavid Schultz 
384cc36ccd1SDavid Schultz 	if ( (i = k & 3) !=0)
385cc36ccd1SDavid Schultz 		b = multadd(b, p05[i-1], 0);
386cc36ccd1SDavid Schultz 
387cc36ccd1SDavid Schultz 	if (!(k >>= 2))
388cc36ccd1SDavid Schultz 		return b;
389cc36ccd1SDavid Schultz 	if ((p5 = p5s) == 0) {
390cc36ccd1SDavid Schultz 		/* first time */
391cc36ccd1SDavid Schultz #ifdef MULTIPLE_THREADS
392cc36ccd1SDavid Schultz 		ACQUIRE_DTOA_LOCK(1);
393cc36ccd1SDavid Schultz 		if (!(p5 = p5s)) {
394cc36ccd1SDavid Schultz 			p5 = p5s = i2b(625);
395cc36ccd1SDavid Schultz 			p5->next = 0;
396cc36ccd1SDavid Schultz 			}
397cc36ccd1SDavid Schultz 		FREE_DTOA_LOCK(1);
398cc36ccd1SDavid Schultz #else
399cc36ccd1SDavid Schultz 		p5 = p5s = i2b(625);
400cc36ccd1SDavid Schultz 		p5->next = 0;
401cc36ccd1SDavid Schultz #endif
402cc36ccd1SDavid Schultz 		}
403cc36ccd1SDavid Schultz 	for(;;) {
404cc36ccd1SDavid Schultz 		if (k & 1) {
405cc36ccd1SDavid Schultz 			b1 = mult(b, p5);
406cc36ccd1SDavid Schultz 			Bfree(b);
407cc36ccd1SDavid Schultz 			b = b1;
408cc36ccd1SDavid Schultz 			}
409cc36ccd1SDavid Schultz 		if (!(k >>= 1))
410cc36ccd1SDavid Schultz 			break;
411cc36ccd1SDavid Schultz 		if ((p51 = p5->next) == 0) {
412cc36ccd1SDavid Schultz #ifdef MULTIPLE_THREADS
413cc36ccd1SDavid Schultz 			ACQUIRE_DTOA_LOCK(1);
414cc36ccd1SDavid Schultz 			if (!(p51 = p5->next)) {
415cc36ccd1SDavid Schultz 				p51 = p5->next = mult(p5,p5);
416cc36ccd1SDavid Schultz 				p51->next = 0;
417cc36ccd1SDavid Schultz 				}
418cc36ccd1SDavid Schultz 			FREE_DTOA_LOCK(1);
419cc36ccd1SDavid Schultz #else
420cc36ccd1SDavid Schultz 			p51 = p5->next = mult(p5,p5);
421cc36ccd1SDavid Schultz 			p51->next = 0;
422cc36ccd1SDavid Schultz #endif
423cc36ccd1SDavid Schultz 			}
424cc36ccd1SDavid Schultz 		p5 = p51;
425cc36ccd1SDavid Schultz 		}
426cc36ccd1SDavid Schultz 	return b;
427cc36ccd1SDavid Schultz 	}
428cc36ccd1SDavid Schultz 
429cc36ccd1SDavid Schultz  Bigint *
430cc36ccd1SDavid Schultz lshift
431cc36ccd1SDavid Schultz #ifdef KR_headers
432cc36ccd1SDavid Schultz 	(b, k) Bigint *b; int k;
433cc36ccd1SDavid Schultz #else
434cc36ccd1SDavid Schultz 	(Bigint *b, int k)
435cc36ccd1SDavid Schultz #endif
436cc36ccd1SDavid Schultz {
437cc36ccd1SDavid Schultz 	int i, k1, n, n1;
438cc36ccd1SDavid Schultz 	Bigint *b1;
439cc36ccd1SDavid Schultz 	ULong *x, *x1, *xe, z;
440cc36ccd1SDavid Schultz 
441cc36ccd1SDavid Schultz 	n = k >> kshift;
442cc36ccd1SDavid Schultz 	k1 = b->k;
443cc36ccd1SDavid Schultz 	n1 = n + b->wds + 1;
444cc36ccd1SDavid Schultz 	for(i = b->maxwds; n1 > i; i <<= 1)
445cc36ccd1SDavid Schultz 		k1++;
446cc36ccd1SDavid Schultz 	b1 = Balloc(k1);
447cc36ccd1SDavid Schultz 	x1 = b1->x;
448cc36ccd1SDavid Schultz 	for(i = 0; i < n; i++)
449cc36ccd1SDavid Schultz 		*x1++ = 0;
450cc36ccd1SDavid Schultz 	x = b->x;
451cc36ccd1SDavid Schultz 	xe = x + b->wds;
452cc36ccd1SDavid Schultz 	if (k &= kmask) {
453cc36ccd1SDavid Schultz #ifdef Pack_32
454cc36ccd1SDavid Schultz 		k1 = 32 - k;
455cc36ccd1SDavid Schultz 		z = 0;
456cc36ccd1SDavid Schultz 		do {
457cc36ccd1SDavid Schultz 			*x1++ = *x << k | z;
458cc36ccd1SDavid Schultz 			z = *x++ >> k1;
459cc36ccd1SDavid Schultz 			}
460cc36ccd1SDavid Schultz 			while(x < xe);
461cc36ccd1SDavid Schultz 		if ((*x1 = z) !=0)
462cc36ccd1SDavid Schultz 			++n1;
463cc36ccd1SDavid Schultz #else
464cc36ccd1SDavid Schultz 		k1 = 16 - k;
465cc36ccd1SDavid Schultz 		z = 0;
466cc36ccd1SDavid Schultz 		do {
467cc36ccd1SDavid Schultz 			*x1++ = *x << k  & 0xffff | z;
468cc36ccd1SDavid Schultz 			z = *x++ >> k1;
469cc36ccd1SDavid Schultz 			}
470cc36ccd1SDavid Schultz 			while(x < xe);
471cc36ccd1SDavid Schultz 		if (*x1 = z)
472cc36ccd1SDavid Schultz 			++n1;
473cc36ccd1SDavid Schultz #endif
474cc36ccd1SDavid Schultz 		}
475cc36ccd1SDavid Schultz 	else do
476cc36ccd1SDavid Schultz 		*x1++ = *x++;
477cc36ccd1SDavid Schultz 		while(x < xe);
478cc36ccd1SDavid Schultz 	b1->wds = n1 - 1;
479cc36ccd1SDavid Schultz 	Bfree(b);
480cc36ccd1SDavid Schultz 	return b1;
481cc36ccd1SDavid Schultz 	}
482cc36ccd1SDavid Schultz 
483cc36ccd1SDavid Schultz  int
484cc36ccd1SDavid Schultz cmp
485cc36ccd1SDavid Schultz #ifdef KR_headers
486cc36ccd1SDavid Schultz 	(a, b) Bigint *a, *b;
487cc36ccd1SDavid Schultz #else
488cc36ccd1SDavid Schultz 	(Bigint *a, Bigint *b)
489cc36ccd1SDavid Schultz #endif
490cc36ccd1SDavid Schultz {
491cc36ccd1SDavid Schultz 	ULong *xa, *xa0, *xb, *xb0;
492cc36ccd1SDavid Schultz 	int i, j;
493cc36ccd1SDavid Schultz 
494cc36ccd1SDavid Schultz 	i = a->wds;
495cc36ccd1SDavid Schultz 	j = b->wds;
496cc36ccd1SDavid Schultz #ifdef DEBUG
497cc36ccd1SDavid Schultz 	if (i > 1 && !a->x[i-1])
498cc36ccd1SDavid Schultz 		Bug("cmp called with a->x[a->wds-1] == 0");
499cc36ccd1SDavid Schultz 	if (j > 1 && !b->x[j-1])
500cc36ccd1SDavid Schultz 		Bug("cmp called with b->x[b->wds-1] == 0");
501cc36ccd1SDavid Schultz #endif
502cc36ccd1SDavid Schultz 	if (i -= j)
503cc36ccd1SDavid Schultz 		return i;
504cc36ccd1SDavid Schultz 	xa0 = a->x;
505cc36ccd1SDavid Schultz 	xa = xa0 + j;
506cc36ccd1SDavid Schultz 	xb0 = b->x;
507cc36ccd1SDavid Schultz 	xb = xb0 + j;
508cc36ccd1SDavid Schultz 	for(;;) {
509cc36ccd1SDavid Schultz 		if (*--xa != *--xb)
510cc36ccd1SDavid Schultz 			return *xa < *xb ? -1 : 1;
511cc36ccd1SDavid Schultz 		if (xa <= xa0)
512cc36ccd1SDavid Schultz 			break;
513cc36ccd1SDavid Schultz 		}
514cc36ccd1SDavid Schultz 	return 0;
515cc36ccd1SDavid Schultz 	}
516cc36ccd1SDavid Schultz 
517cc36ccd1SDavid Schultz  Bigint *
518cc36ccd1SDavid Schultz diff
519cc36ccd1SDavid Schultz #ifdef KR_headers
520cc36ccd1SDavid Schultz 	(a, b) Bigint *a, *b;
521cc36ccd1SDavid Schultz #else
522cc36ccd1SDavid Schultz 	(Bigint *a, Bigint *b)
523cc36ccd1SDavid Schultz #endif
524cc36ccd1SDavid Schultz {
525cc36ccd1SDavid Schultz 	Bigint *c;
526cc36ccd1SDavid Schultz 	int i, wa, wb;
527cc36ccd1SDavid Schultz 	ULong *xa, *xae, *xb, *xbe, *xc;
528cc36ccd1SDavid Schultz #ifdef ULLong
529cc36ccd1SDavid Schultz 	ULLong borrow, y;
530cc36ccd1SDavid Schultz #else
531cc36ccd1SDavid Schultz 	ULong borrow, y;
532cc36ccd1SDavid Schultz #ifdef Pack_32
533cc36ccd1SDavid Schultz 	ULong z;
534cc36ccd1SDavid Schultz #endif
535cc36ccd1SDavid Schultz #endif
536cc36ccd1SDavid Schultz 
537cc36ccd1SDavid Schultz 	i = cmp(a,b);
538cc36ccd1SDavid Schultz 	if (!i) {
539cc36ccd1SDavid Schultz 		c = Balloc(0);
540cc36ccd1SDavid Schultz 		c->wds = 1;
541cc36ccd1SDavid Schultz 		c->x[0] = 0;
542cc36ccd1SDavid Schultz 		return c;
543cc36ccd1SDavid Schultz 		}
544cc36ccd1SDavid Schultz 	if (i < 0) {
545cc36ccd1SDavid Schultz 		c = a;
546cc36ccd1SDavid Schultz 		a = b;
547cc36ccd1SDavid Schultz 		b = c;
548cc36ccd1SDavid Schultz 		i = 1;
549cc36ccd1SDavid Schultz 		}
550cc36ccd1SDavid Schultz 	else
551cc36ccd1SDavid Schultz 		i = 0;
552cc36ccd1SDavid Schultz 	c = Balloc(a->k);
553cc36ccd1SDavid Schultz 	c->sign = i;
554cc36ccd1SDavid Schultz 	wa = a->wds;
555cc36ccd1SDavid Schultz 	xa = a->x;
556cc36ccd1SDavid Schultz 	xae = xa + wa;
557cc36ccd1SDavid Schultz 	wb = b->wds;
558cc36ccd1SDavid Schultz 	xb = b->x;
559cc36ccd1SDavid Schultz 	xbe = xb + wb;
560cc36ccd1SDavid Schultz 	xc = c->x;
561cc36ccd1SDavid Schultz 	borrow = 0;
562cc36ccd1SDavid Schultz #ifdef ULLong
563cc36ccd1SDavid Schultz 	do {
564cc36ccd1SDavid Schultz 		y = (ULLong)*xa++ - *xb++ - borrow;
565cc36ccd1SDavid Schultz 		borrow = y >> 32 & 1UL;
566cc36ccd1SDavid Schultz 		*xc++ = y & 0xffffffffUL;
567cc36ccd1SDavid Schultz 		}
568cc36ccd1SDavid Schultz 		while(xb < xbe);
569cc36ccd1SDavid Schultz 	while(xa < xae) {
570cc36ccd1SDavid Schultz 		y = *xa++ - borrow;
571cc36ccd1SDavid Schultz 		borrow = y >> 32 & 1UL;
572cc36ccd1SDavid Schultz 		*xc++ = y & 0xffffffffUL;
573cc36ccd1SDavid Schultz 		}
574cc36ccd1SDavid Schultz #else
575cc36ccd1SDavid Schultz #ifdef Pack_32
576cc36ccd1SDavid Schultz 	do {
577cc36ccd1SDavid Schultz 		y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
578cc36ccd1SDavid Schultz 		borrow = (y & 0x10000) >> 16;
579cc36ccd1SDavid Schultz 		z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
580cc36ccd1SDavid Schultz 		borrow = (z & 0x10000) >> 16;
581cc36ccd1SDavid Schultz 		Storeinc(xc, z, y);
582cc36ccd1SDavid Schultz 		}
583cc36ccd1SDavid Schultz 		while(xb < xbe);
584cc36ccd1SDavid Schultz 	while(xa < xae) {
585cc36ccd1SDavid Schultz 		y = (*xa & 0xffff) - borrow;
586cc36ccd1SDavid Schultz 		borrow = (y & 0x10000) >> 16;
587cc36ccd1SDavid Schultz 		z = (*xa++ >> 16) - borrow;
588cc36ccd1SDavid Schultz 		borrow = (z & 0x10000) >> 16;
589cc36ccd1SDavid Schultz 		Storeinc(xc, z, y);
590cc36ccd1SDavid Schultz 		}
591cc36ccd1SDavid Schultz #else
592cc36ccd1SDavid Schultz 	do {
593cc36ccd1SDavid Schultz 		y = *xa++ - *xb++ - borrow;
594cc36ccd1SDavid Schultz 		borrow = (y & 0x10000) >> 16;
595cc36ccd1SDavid Schultz 		*xc++ = y & 0xffff;
596cc36ccd1SDavid Schultz 		}
597cc36ccd1SDavid Schultz 		while(xb < xbe);
598cc36ccd1SDavid Schultz 	while(xa < xae) {
599cc36ccd1SDavid Schultz 		y = *xa++ - borrow;
600cc36ccd1SDavid Schultz 		borrow = (y & 0x10000) >> 16;
601cc36ccd1SDavid Schultz 		*xc++ = y & 0xffff;
602cc36ccd1SDavid Schultz 		}
603cc36ccd1SDavid Schultz #endif
604cc36ccd1SDavid Schultz #endif
605cc36ccd1SDavid Schultz 	while(!*--xc)
606cc36ccd1SDavid Schultz 		wa--;
607cc36ccd1SDavid Schultz 	c->wds = wa;
608cc36ccd1SDavid Schultz 	return c;
609cc36ccd1SDavid Schultz 	}
610cc36ccd1SDavid Schultz 
611cc36ccd1SDavid Schultz  double
612cc36ccd1SDavid Schultz b2d
613cc36ccd1SDavid Schultz #ifdef KR_headers
614cc36ccd1SDavid Schultz 	(a, e) Bigint *a; int *e;
615cc36ccd1SDavid Schultz #else
616cc36ccd1SDavid Schultz 	(Bigint *a, int *e)
617cc36ccd1SDavid Schultz #endif
618cc36ccd1SDavid Schultz {
619cc36ccd1SDavid Schultz 	ULong *xa, *xa0, w, y, z;
620cc36ccd1SDavid Schultz 	int k;
621cc36ccd1SDavid Schultz 	double d;
622cc36ccd1SDavid Schultz #ifdef VAX
623cc36ccd1SDavid Schultz 	ULong d0, d1;
624cc36ccd1SDavid Schultz #else
625cc36ccd1SDavid Schultz #define d0 word0(d)
626cc36ccd1SDavid Schultz #define d1 word1(d)
627cc36ccd1SDavid Schultz #endif
628cc36ccd1SDavid Schultz 
629cc36ccd1SDavid Schultz 	xa0 = a->x;
630cc36ccd1SDavid Schultz 	xa = xa0 + a->wds;
631cc36ccd1SDavid Schultz 	y = *--xa;
632cc36ccd1SDavid Schultz #ifdef DEBUG
633cc36ccd1SDavid Schultz 	if (!y) Bug("zero y in b2d");
634cc36ccd1SDavid Schultz #endif
635cc36ccd1SDavid Schultz 	k = hi0bits(y);
636cc36ccd1SDavid Schultz 	*e = 32 - k;
637cc36ccd1SDavid Schultz #ifdef Pack_32
638cc36ccd1SDavid Schultz 	if (k < Ebits) {
639cc36ccd1SDavid Schultz 		d0 = Exp_1 | y >> Ebits - k;
640cc36ccd1SDavid Schultz 		w = xa > xa0 ? *--xa : 0;
641cc36ccd1SDavid Schultz 		d1 = y << (32-Ebits) + k | w >> Ebits - k;
642cc36ccd1SDavid Schultz 		goto ret_d;
643cc36ccd1SDavid Schultz 		}
644cc36ccd1SDavid Schultz 	z = xa > xa0 ? *--xa : 0;
645cc36ccd1SDavid Schultz 	if (k -= Ebits) {
646cc36ccd1SDavid Schultz 		d0 = Exp_1 | y << k | z >> 32 - k;
647cc36ccd1SDavid Schultz 		y = xa > xa0 ? *--xa : 0;
648cc36ccd1SDavid Schultz 		d1 = z << k | y >> 32 - k;
649cc36ccd1SDavid Schultz 		}
650cc36ccd1SDavid Schultz 	else {
651cc36ccd1SDavid Schultz 		d0 = Exp_1 | y;
652cc36ccd1SDavid Schultz 		d1 = z;
653cc36ccd1SDavid Schultz 		}
654cc36ccd1SDavid Schultz #else
655cc36ccd1SDavid Schultz 	if (k < Ebits + 16) {
656cc36ccd1SDavid Schultz 		z = xa > xa0 ? *--xa : 0;
657cc36ccd1SDavid Schultz 		d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
658cc36ccd1SDavid Schultz 		w = xa > xa0 ? *--xa : 0;
659cc36ccd1SDavid Schultz 		y = xa > xa0 ? *--xa : 0;
660cc36ccd1SDavid Schultz 		d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
661cc36ccd1SDavid Schultz 		goto ret_d;
662cc36ccd1SDavid Schultz 		}
663cc36ccd1SDavid Schultz 	z = xa > xa0 ? *--xa : 0;
664cc36ccd1SDavid Schultz 	w = xa > xa0 ? *--xa : 0;
665cc36ccd1SDavid Schultz 	k -= Ebits + 16;
666cc36ccd1SDavid Schultz 	d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
667cc36ccd1SDavid Schultz 	y = xa > xa0 ? *--xa : 0;
668cc36ccd1SDavid Schultz 	d1 = w << k + 16 | y << k;
669cc36ccd1SDavid Schultz #endif
670cc36ccd1SDavid Schultz  ret_d:
671cc36ccd1SDavid Schultz #ifdef VAX
672cc36ccd1SDavid Schultz 	word0(d) = d0 >> 16 | d0 << 16;
673cc36ccd1SDavid Schultz 	word1(d) = d1 >> 16 | d1 << 16;
674cc36ccd1SDavid Schultz #endif
675cc36ccd1SDavid Schultz 	return dval(d);
676cc36ccd1SDavid Schultz 	}
677cc36ccd1SDavid Schultz #undef d0
678cc36ccd1SDavid Schultz #undef d1
679cc36ccd1SDavid Schultz 
680cc36ccd1SDavid Schultz  Bigint *
681cc36ccd1SDavid Schultz d2b
682cc36ccd1SDavid Schultz #ifdef KR_headers
683cc36ccd1SDavid Schultz 	(d, e, bits) double d; int *e, *bits;
684cc36ccd1SDavid Schultz #else
685cc36ccd1SDavid Schultz 	(double d, int *e, int *bits)
686cc36ccd1SDavid Schultz #endif
687cc36ccd1SDavid Schultz {
688cc36ccd1SDavid Schultz 	Bigint *b;
689cc36ccd1SDavid Schultz 	int de, i, k;
690cc36ccd1SDavid Schultz 	ULong *x, y, z;
691cc36ccd1SDavid Schultz #ifdef VAX
692cc36ccd1SDavid Schultz 	ULong d0, d1;
693cc36ccd1SDavid Schultz 	d0 = word0(d) >> 16 | word0(d) << 16;
694cc36ccd1SDavid Schultz 	d1 = word1(d) >> 16 | word1(d) << 16;
695cc36ccd1SDavid Schultz #else
696cc36ccd1SDavid Schultz #define d0 word0(d)
697cc36ccd1SDavid Schultz #define d1 word1(d)
698cc36ccd1SDavid Schultz #endif
699cc36ccd1SDavid Schultz 
700cc36ccd1SDavid Schultz #ifdef Pack_32
701cc36ccd1SDavid Schultz 	b = Balloc(1);
702cc36ccd1SDavid Schultz #else
703cc36ccd1SDavid Schultz 	b = Balloc(2);
704cc36ccd1SDavid Schultz #endif
705cc36ccd1SDavid Schultz 	x = b->x;
706cc36ccd1SDavid Schultz 
707cc36ccd1SDavid Schultz 	z = d0 & Frac_mask;
708cc36ccd1SDavid Schultz 	d0 &= 0x7fffffff;	/* clear sign bit, which we ignore */
709cc36ccd1SDavid Schultz #ifdef Sudden_Underflow
710cc36ccd1SDavid Schultz 	de = (int)(d0 >> Exp_shift);
711cc36ccd1SDavid Schultz #ifndef IBM
712cc36ccd1SDavid Schultz 	z |= Exp_msk11;
713cc36ccd1SDavid Schultz #endif
714cc36ccd1SDavid Schultz #else
715cc36ccd1SDavid Schultz 	if ( (de = (int)(d0 >> Exp_shift)) !=0)
716cc36ccd1SDavid Schultz 		z |= Exp_msk1;
717cc36ccd1SDavid Schultz #endif
718cc36ccd1SDavid Schultz #ifdef Pack_32
719cc36ccd1SDavid Schultz 	if ( (y = d1) !=0) {
720cc36ccd1SDavid Schultz 		if ( (k = lo0bits(&y)) !=0) {
721cc36ccd1SDavid Schultz 			x[0] = y | z << 32 - k;
722cc36ccd1SDavid Schultz 			z >>= k;
723cc36ccd1SDavid Schultz 			}
724cc36ccd1SDavid Schultz 		else
725cc36ccd1SDavid Schultz 			x[0] = y;
726cc36ccd1SDavid Schultz 		i = b->wds = (x[1] = z) !=0 ? 2 : 1;
727cc36ccd1SDavid Schultz 		}
728cc36ccd1SDavid Schultz 	else {
729cc36ccd1SDavid Schultz #ifdef DEBUG
730cc36ccd1SDavid Schultz 		if (!z)
731cc36ccd1SDavid Schultz 			Bug("Zero passed to d2b");
732cc36ccd1SDavid Schultz #endif
733cc36ccd1SDavid Schultz 		k = lo0bits(&z);
734cc36ccd1SDavid Schultz 		x[0] = z;
735cc36ccd1SDavid Schultz 		i = b->wds = 1;
736cc36ccd1SDavid Schultz 		k += 32;
737cc36ccd1SDavid Schultz 		}
738cc36ccd1SDavid Schultz #else
739cc36ccd1SDavid Schultz 	if ( (y = d1) !=0) {
740cc36ccd1SDavid Schultz 		if ( (k = lo0bits(&y)) !=0)
741cc36ccd1SDavid Schultz 			if (k >= 16) {
742cc36ccd1SDavid Schultz 				x[0] = y | z << 32 - k & 0xffff;
743cc36ccd1SDavid Schultz 				x[1] = z >> k - 16 & 0xffff;
744cc36ccd1SDavid Schultz 				x[2] = z >> k;
745cc36ccd1SDavid Schultz 				i = 2;
746cc36ccd1SDavid Schultz 				}
747cc36ccd1SDavid Schultz 			else {
748cc36ccd1SDavid Schultz 				x[0] = y & 0xffff;
749cc36ccd1SDavid Schultz 				x[1] = y >> 16 | z << 16 - k & 0xffff;
750cc36ccd1SDavid Schultz 				x[2] = z >> k & 0xffff;
751cc36ccd1SDavid Schultz 				x[3] = z >> k+16;
752cc36ccd1SDavid Schultz 				i = 3;
753cc36ccd1SDavid Schultz 				}
754cc36ccd1SDavid Schultz 		else {
755cc36ccd1SDavid Schultz 			x[0] = y & 0xffff;
756cc36ccd1SDavid Schultz 			x[1] = y >> 16;
757cc36ccd1SDavid Schultz 			x[2] = z & 0xffff;
758cc36ccd1SDavid Schultz 			x[3] = z >> 16;
759cc36ccd1SDavid Schultz 			i = 3;
760cc36ccd1SDavid Schultz 			}
761cc36ccd1SDavid Schultz 		}
762cc36ccd1SDavid Schultz 	else {
763cc36ccd1SDavid Schultz #ifdef DEBUG
764cc36ccd1SDavid Schultz 		if (!z)
765cc36ccd1SDavid Schultz 			Bug("Zero passed to d2b");
766cc36ccd1SDavid Schultz #endif
767cc36ccd1SDavid Schultz 		k = lo0bits(&z);
768cc36ccd1SDavid Schultz 		if (k >= 16) {
769cc36ccd1SDavid Schultz 			x[0] = z;
770cc36ccd1SDavid Schultz 			i = 0;
771cc36ccd1SDavid Schultz 			}
772cc36ccd1SDavid Schultz 		else {
773cc36ccd1SDavid Schultz 			x[0] = z & 0xffff;
774cc36ccd1SDavid Schultz 			x[1] = z >> 16;
775cc36ccd1SDavid Schultz 			i = 1;
776cc36ccd1SDavid Schultz 			}
777cc36ccd1SDavid Schultz 		k += 32;
778cc36ccd1SDavid Schultz 		}
779cc36ccd1SDavid Schultz 	while(!x[i])
780cc36ccd1SDavid Schultz 		--i;
781cc36ccd1SDavid Schultz 	b->wds = i + 1;
782cc36ccd1SDavid Schultz #endif
783cc36ccd1SDavid Schultz #ifndef Sudden_Underflow
784cc36ccd1SDavid Schultz 	if (de) {
785cc36ccd1SDavid Schultz #endif
786cc36ccd1SDavid Schultz #ifdef IBM
787cc36ccd1SDavid Schultz 		*e = (de - Bias - (P-1) << 2) + k;
788cc36ccd1SDavid Schultz 		*bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
789cc36ccd1SDavid Schultz #else
790cc36ccd1SDavid Schultz 		*e = de - Bias - (P-1) + k;
791cc36ccd1SDavid Schultz 		*bits = P - k;
792cc36ccd1SDavid Schultz #endif
793cc36ccd1SDavid Schultz #ifndef Sudden_Underflow
794cc36ccd1SDavid Schultz 		}
795cc36ccd1SDavid Schultz 	else {
796cc36ccd1SDavid Schultz 		*e = de - Bias - (P-1) + 1 + k;
797cc36ccd1SDavid Schultz #ifdef Pack_32
798cc36ccd1SDavid Schultz 		*bits = 32*i - hi0bits(x[i-1]);
799cc36ccd1SDavid Schultz #else
800cc36ccd1SDavid Schultz 		*bits = (i+2)*16 - hi0bits(x[i]);
801cc36ccd1SDavid Schultz #endif
802cc36ccd1SDavid Schultz 		}
803cc36ccd1SDavid Schultz #endif
804cc36ccd1SDavid Schultz 	return b;
805cc36ccd1SDavid Schultz 	}
806cc36ccd1SDavid Schultz #undef d0
807cc36ccd1SDavid Schultz #undef d1
808cc36ccd1SDavid Schultz 
809cc36ccd1SDavid Schultz  CONST double
810cc36ccd1SDavid Schultz #ifdef IEEE_Arith
811cc36ccd1SDavid Schultz bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
812cc36ccd1SDavid Schultz CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
813cc36ccd1SDavid Schultz 		};
814cc36ccd1SDavid Schultz #else
815cc36ccd1SDavid Schultz #ifdef IBM
816cc36ccd1SDavid Schultz bigtens[] = { 1e16, 1e32, 1e64 };
817cc36ccd1SDavid Schultz CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
818cc36ccd1SDavid Schultz #else
819cc36ccd1SDavid Schultz bigtens[] = { 1e16, 1e32 };
820cc36ccd1SDavid Schultz CONST double tinytens[] = { 1e-16, 1e-32 };
821cc36ccd1SDavid Schultz #endif
822cc36ccd1SDavid Schultz #endif
823cc36ccd1SDavid Schultz 
824cc36ccd1SDavid Schultz  CONST double
825cc36ccd1SDavid Schultz tens[] = {
826cc36ccd1SDavid Schultz 		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
827cc36ccd1SDavid Schultz 		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
828cc36ccd1SDavid Schultz 		1e20, 1e21, 1e22
829cc36ccd1SDavid Schultz #ifdef VAX
830cc36ccd1SDavid Schultz 		, 1e23, 1e24
831cc36ccd1SDavid Schultz #endif
832cc36ccd1SDavid Schultz 		};
833cc36ccd1SDavid Schultz 
834cc36ccd1SDavid Schultz  char *
835cc36ccd1SDavid Schultz #ifdef KR_headers
836cc36ccd1SDavid Schultz strcp_D2A(a, b) char *a; char *b;
837cc36ccd1SDavid Schultz #else
838cc36ccd1SDavid Schultz strcp_D2A(char *a, CONST char *b)
839cc36ccd1SDavid Schultz #endif
840cc36ccd1SDavid Schultz {
841cc36ccd1SDavid Schultz 	while(*a = *b++)
842cc36ccd1SDavid Schultz 		a++;
843cc36ccd1SDavid Schultz 	return a;
844cc36ccd1SDavid Schultz 	}
845cc36ccd1SDavid Schultz 
846cc36ccd1SDavid Schultz #ifdef NO_STRING_H
847cc36ccd1SDavid Schultz 
848cc36ccd1SDavid Schultz  Char *
849cc36ccd1SDavid Schultz #ifdef KR_headers
850cc36ccd1SDavid Schultz memcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
851cc36ccd1SDavid Schultz #else
852cc36ccd1SDavid Schultz memcpy_D2A(void *a1, void *b1, size_t len)
853cc36ccd1SDavid Schultz #endif
854cc36ccd1SDavid Schultz {
855cc36ccd1SDavid Schultz 	register char *a = (char*)a1, *ae = a + len;
856cc36ccd1SDavid Schultz 	register char *b = (char*)b1, *a0 = a;
857cc36ccd1SDavid Schultz 	while(a < ae)
858cc36ccd1SDavid Schultz 		*a++ = *b++;
859cc36ccd1SDavid Schultz 	return a0;
860cc36ccd1SDavid Schultz 	}
861cc36ccd1SDavid Schultz 
862cc36ccd1SDavid Schultz #endif /* NO_STRING_H */
863