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