xref: /minix3/lib/libc/gdtoa/misc.c (revision f14fb602092e015ff630df58e17c2a9cd57d29b3)
1*f14fb602SLionel Sambuc /* $NetBSD: misc.c,v 1.11 2011/11/21 09:46:19 mlelstv Exp $ */
22fe8fb19SBen Gras 
32fe8fb19SBen Gras /****************************************************************
42fe8fb19SBen Gras 
52fe8fb19SBen Gras The author of this software is David M. Gay.
62fe8fb19SBen Gras 
72fe8fb19SBen Gras Copyright (C) 1998, 1999 by Lucent Technologies
82fe8fb19SBen Gras All Rights Reserved
92fe8fb19SBen Gras 
102fe8fb19SBen Gras Permission to use, copy, modify, and distribute this software and
112fe8fb19SBen Gras its documentation for any purpose and without fee is hereby
122fe8fb19SBen Gras granted, provided that the above copyright notice appear in all
132fe8fb19SBen Gras copies and that both that the copyright notice and this
142fe8fb19SBen Gras permission notice and warranty disclaimer appear in supporting
152fe8fb19SBen Gras documentation, and that the name of Lucent or any of its entities
162fe8fb19SBen Gras not be used in advertising or publicity pertaining to
172fe8fb19SBen Gras distribution of the software without specific, written prior
182fe8fb19SBen Gras permission.
192fe8fb19SBen Gras 
202fe8fb19SBen Gras LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
212fe8fb19SBen Gras INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
222fe8fb19SBen Gras IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
232fe8fb19SBen Gras SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
242fe8fb19SBen Gras WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
252fe8fb19SBen Gras IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
262fe8fb19SBen Gras ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
272fe8fb19SBen Gras THIS SOFTWARE.
282fe8fb19SBen Gras 
292fe8fb19SBen Gras ****************************************************************/
302fe8fb19SBen Gras 
312fe8fb19SBen Gras /* Please send bug reports to David M. Gay (dmg at acm dot org,
322fe8fb19SBen Gras  * with " at " changed at "@" and " dot " changed to ".").	*/
332fe8fb19SBen Gras 
342fe8fb19SBen Gras #include "gdtoaimp.h"
352fe8fb19SBen Gras 
362fe8fb19SBen Gras  static Bigint *freelist[Kmax+1];
372fe8fb19SBen Gras #ifndef Omit_Private_Memory
382fe8fb19SBen Gras #ifndef PRIVATE_MEM
392fe8fb19SBen Gras #define PRIVATE_MEM 2304
402fe8fb19SBen Gras #endif
412fe8fb19SBen Gras #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
422fe8fb19SBen Gras static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
432fe8fb19SBen Gras #endif
442fe8fb19SBen Gras 
452fe8fb19SBen Gras  Bigint *
Balloc(k)462fe8fb19SBen Gras Balloc
472fe8fb19SBen Gras #ifdef KR_headers
482fe8fb19SBen Gras 	(k) int k;
492fe8fb19SBen Gras #else
502fe8fb19SBen Gras 	(int k)
512fe8fb19SBen Gras #endif
522fe8fb19SBen Gras {
532fe8fb19SBen Gras 	int x;
542fe8fb19SBen Gras 	Bigint *rv;
552fe8fb19SBen Gras #ifndef Omit_Private_Memory
56*f14fb602SLionel Sambuc 	size_t len;
572fe8fb19SBen Gras #endif
582fe8fb19SBen Gras 
592fe8fb19SBen Gras 	ACQUIRE_DTOA_LOCK(0);
60*f14fb602SLionel Sambuc 	/* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
61*f14fb602SLionel Sambuc 	/* but this case seems very unlikely. */
62*f14fb602SLionel Sambuc 	if ((size_t)k <= Kmax && (rv = freelist[k]) !=0) {
632fe8fb19SBen Gras 		freelist[k] = rv->next;
642fe8fb19SBen Gras 		}
652fe8fb19SBen Gras 	else {
662fe8fb19SBen Gras 		x = 1 << k;
672fe8fb19SBen Gras #ifdef Omit_Private_Memory
682fe8fb19SBen Gras 		rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
692fe8fb19SBen Gras #else
702fe8fb19SBen Gras 		len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
712fe8fb19SBen Gras 			/sizeof(double);
72*f14fb602SLionel Sambuc 		if ((size_t)k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
732fe8fb19SBen Gras 			rv = (Bigint*)(void *)pmem_next;
742fe8fb19SBen Gras 			pmem_next += len;
752fe8fb19SBen Gras 			}
762fe8fb19SBen Gras 		else
772fe8fb19SBen Gras 			rv = (Bigint*)MALLOC(len*sizeof(double));
782fe8fb19SBen Gras #endif
79*f14fb602SLionel Sambuc 		if (rv == NULL) {
80*f14fb602SLionel Sambuc 			FREE_DTOA_LOCK(0);
812fe8fb19SBen Gras 			return NULL;
82*f14fb602SLionel Sambuc 		}
832fe8fb19SBen Gras 		rv->k = k;
842fe8fb19SBen Gras 		rv->maxwds = x;
852fe8fb19SBen Gras 		}
862fe8fb19SBen Gras 	FREE_DTOA_LOCK(0);
872fe8fb19SBen Gras 	rv->sign = rv->wds = 0;
882fe8fb19SBen Gras 	return rv;
892fe8fb19SBen Gras 	}
902fe8fb19SBen Gras 
912fe8fb19SBen Gras  void
Bfree(v)922fe8fb19SBen Gras Bfree
932fe8fb19SBen Gras #ifdef KR_headers
942fe8fb19SBen Gras 	(v) Bigint *v;
952fe8fb19SBen Gras #else
962fe8fb19SBen Gras 	(Bigint *v)
972fe8fb19SBen Gras #endif
982fe8fb19SBen Gras {
992fe8fb19SBen Gras 	if (v) {
100*f14fb602SLionel Sambuc 		if ((size_t)v->k > Kmax)
101*f14fb602SLionel Sambuc #ifdef FREE
102*f14fb602SLionel Sambuc 			FREE((void*)v);
103*f14fb602SLionel Sambuc #else
104*f14fb602SLionel Sambuc 			free((void*)v);
105*f14fb602SLionel Sambuc #endif
106*f14fb602SLionel Sambuc 		else {
1072fe8fb19SBen Gras 			ACQUIRE_DTOA_LOCK(0);
1082fe8fb19SBen Gras 			v->next = freelist[v->k];
1092fe8fb19SBen Gras 			freelist[v->k] = v;
1102fe8fb19SBen Gras 			FREE_DTOA_LOCK(0);
1112fe8fb19SBen Gras 			}
1122fe8fb19SBen Gras 		}
113*f14fb602SLionel Sambuc 	}
1142fe8fb19SBen Gras 
1152fe8fb19SBen Gras  int
lo0bits(y)1162fe8fb19SBen Gras lo0bits
1172fe8fb19SBen Gras #ifdef KR_headers
1182fe8fb19SBen Gras 	(y) ULong *y;
1192fe8fb19SBen Gras #else
1202fe8fb19SBen Gras 	(ULong *y)
1212fe8fb19SBen Gras #endif
1222fe8fb19SBen Gras {
1232fe8fb19SBen Gras 	int k;
1242fe8fb19SBen Gras 	ULong x = *y;
1252fe8fb19SBen Gras 
1262fe8fb19SBen Gras 	if (x & 7) {
1272fe8fb19SBen Gras 		if (x & 1)
1282fe8fb19SBen Gras 			return 0;
1292fe8fb19SBen Gras 		if (x & 2) {
1302fe8fb19SBen Gras 			*y = x >> 1;
1312fe8fb19SBen Gras 			return 1;
1322fe8fb19SBen Gras 			}
1332fe8fb19SBen Gras 		*y = x >> 2;
1342fe8fb19SBen Gras 		return 2;
1352fe8fb19SBen Gras 		}
1362fe8fb19SBen Gras 	k = 0;
1372fe8fb19SBen Gras 	if (!(x & 0xffff)) {
1382fe8fb19SBen Gras 		k = 16;
1392fe8fb19SBen Gras 		x >>= 16;
1402fe8fb19SBen Gras 		}
1412fe8fb19SBen Gras 	if (!(x & 0xff)) {
1422fe8fb19SBen Gras 		k += 8;
1432fe8fb19SBen Gras 		x >>= 8;
1442fe8fb19SBen Gras 		}
1452fe8fb19SBen Gras 	if (!(x & 0xf)) {
1462fe8fb19SBen Gras 		k += 4;
1472fe8fb19SBen Gras 		x >>= 4;
1482fe8fb19SBen Gras 		}
1492fe8fb19SBen Gras 	if (!(x & 0x3)) {
1502fe8fb19SBen Gras 		k += 2;
1512fe8fb19SBen Gras 		x >>= 2;
1522fe8fb19SBen Gras 		}
1532fe8fb19SBen Gras 	if (!(x & 1)) {
1542fe8fb19SBen Gras 		k++;
1552fe8fb19SBen Gras 		x >>= 1;
1562fe8fb19SBen Gras 		if (!x)
1572fe8fb19SBen Gras 			return 32;
1582fe8fb19SBen Gras 		}
1592fe8fb19SBen Gras 	*y = x;
1602fe8fb19SBen Gras 	return k;
1612fe8fb19SBen Gras 	}
1622fe8fb19SBen Gras 
1632fe8fb19SBen Gras  Bigint *
multadd(b,m,a)1642fe8fb19SBen Gras multadd
1652fe8fb19SBen Gras #ifdef KR_headers
1662fe8fb19SBen Gras 	(b, m, a) Bigint *b; int m, a;
1672fe8fb19SBen Gras #else
1682fe8fb19SBen Gras 	(Bigint *b, int m, int a)	/* multiply by m and add a */
1692fe8fb19SBen Gras #endif
1702fe8fb19SBen Gras {
1712fe8fb19SBen Gras 	int i, wds;
1722fe8fb19SBen Gras #ifdef ULLong
1732fe8fb19SBen Gras 	ULong *x;
1742fe8fb19SBen Gras 	ULLong carry, y;
1752fe8fb19SBen Gras #else
1762fe8fb19SBen Gras 	ULong carry, *x, y;
1772fe8fb19SBen Gras #ifdef Pack_32
1782fe8fb19SBen Gras 	ULong xi, z;
1792fe8fb19SBen Gras #endif
1802fe8fb19SBen Gras #endif
1812fe8fb19SBen Gras 	Bigint *b1;
1822fe8fb19SBen Gras 
1832fe8fb19SBen Gras 	wds = b->wds;
1842fe8fb19SBen Gras 	x = b->x;
1852fe8fb19SBen Gras 	i = 0;
1862fe8fb19SBen Gras 	carry = a;
1872fe8fb19SBen Gras 	do {
1882fe8fb19SBen Gras #ifdef ULLong
1892fe8fb19SBen Gras 		y = *x * (ULLong)m + carry;
1902fe8fb19SBen Gras 		carry = y >> 32;
1912fe8fb19SBen Gras 		/* LINTED conversion */
1922fe8fb19SBen Gras 		*x++ = y & 0xffffffffUL;
1932fe8fb19SBen Gras #else
1942fe8fb19SBen Gras #ifdef Pack_32
1952fe8fb19SBen Gras 		xi = *x;
1962fe8fb19SBen Gras 		y = (xi & 0xffff) * m + carry;
1972fe8fb19SBen Gras 		z = (xi >> 16) * m + (y >> 16);
1982fe8fb19SBen Gras 		carry = z >> 16;
1992fe8fb19SBen Gras 		*x++ = (z << 16) + (y & 0xffff);
2002fe8fb19SBen Gras #else
2012fe8fb19SBen Gras 		y = *x * m + carry;
2022fe8fb19SBen Gras 		carry = y >> 16;
2032fe8fb19SBen Gras 		*x++ = y & 0xffff;
2042fe8fb19SBen Gras #endif
2052fe8fb19SBen Gras #endif
2062fe8fb19SBen Gras 		}
2072fe8fb19SBen Gras 		while(++i < wds);
2082fe8fb19SBen Gras 	if (carry) {
2092fe8fb19SBen Gras 		if (wds >= b->maxwds) {
2102fe8fb19SBen Gras 			b1 = Balloc(b->k+1);
2112fe8fb19SBen Gras 			if (b1 == NULL) {
2122fe8fb19SBen Gras 				Bfree(b);
2132fe8fb19SBen Gras 				return NULL;
2142fe8fb19SBen Gras 				}
2152fe8fb19SBen Gras 			Bcopy(b1, b);
2162fe8fb19SBen Gras 			Bfree(b);
2172fe8fb19SBen Gras 			b = b1;
2182fe8fb19SBen Gras 			}
2192fe8fb19SBen Gras 		/* LINTED conversion */
2202fe8fb19SBen Gras 		b->x[wds++] = carry;
2212fe8fb19SBen Gras 		b->wds = wds;
2222fe8fb19SBen Gras 		}
2232fe8fb19SBen Gras 	return b;
2242fe8fb19SBen Gras 	}
2252fe8fb19SBen Gras 
2262fe8fb19SBen Gras  int
hi0bits_D2A(x)2272fe8fb19SBen Gras hi0bits_D2A
2282fe8fb19SBen Gras #ifdef KR_headers
2292fe8fb19SBen Gras 	(x) ULong x;
2302fe8fb19SBen Gras #else
2312fe8fb19SBen Gras 	(ULong x)
2322fe8fb19SBen Gras #endif
2332fe8fb19SBen Gras {
2342fe8fb19SBen Gras 	int k = 0;
2352fe8fb19SBen Gras 
2362fe8fb19SBen Gras 	if (!(x & 0xffff0000)) {
2372fe8fb19SBen Gras 		k = 16;
2382fe8fb19SBen Gras 		x <<= 16;
2392fe8fb19SBen Gras 		}
2402fe8fb19SBen Gras 	if (!(x & 0xff000000)) {
2412fe8fb19SBen Gras 		k += 8;
2422fe8fb19SBen Gras 		x <<= 8;
2432fe8fb19SBen Gras 		}
2442fe8fb19SBen Gras 	if (!(x & 0xf0000000)) {
2452fe8fb19SBen Gras 		k += 4;
2462fe8fb19SBen Gras 		x <<= 4;
2472fe8fb19SBen Gras 		}
2482fe8fb19SBen Gras 	if (!(x & 0xc0000000)) {
2492fe8fb19SBen Gras 		k += 2;
2502fe8fb19SBen Gras 		x <<= 2;
2512fe8fb19SBen Gras 		}
2522fe8fb19SBen Gras 	if (!(x & 0x80000000)) {
2532fe8fb19SBen Gras 		k++;
2542fe8fb19SBen Gras 		if (!(x & 0x40000000))
2552fe8fb19SBen Gras 			return 32;
2562fe8fb19SBen Gras 		}
2572fe8fb19SBen Gras 	return k;
2582fe8fb19SBen Gras 	}
2592fe8fb19SBen Gras 
2602fe8fb19SBen Gras  Bigint *
i2b(i)2612fe8fb19SBen Gras i2b
2622fe8fb19SBen Gras #ifdef KR_headers
2632fe8fb19SBen Gras 	(i) int i;
2642fe8fb19SBen Gras #else
2652fe8fb19SBen Gras 	(int i)
2662fe8fb19SBen Gras #endif
2672fe8fb19SBen Gras {
2682fe8fb19SBen Gras 	Bigint *b;
2692fe8fb19SBen Gras 
2702fe8fb19SBen Gras 	b = Balloc(1);
2712fe8fb19SBen Gras 	if (b == NULL)
2722fe8fb19SBen Gras 		return NULL;
2732fe8fb19SBen Gras 	b->x[0] = i;
2742fe8fb19SBen Gras 	b->wds = 1;
2752fe8fb19SBen Gras 	return b;
2762fe8fb19SBen Gras 	}
2772fe8fb19SBen Gras 
2782fe8fb19SBen Gras  Bigint *
mult(a,b)2792fe8fb19SBen Gras mult
2802fe8fb19SBen Gras #ifdef KR_headers
2812fe8fb19SBen Gras 	(a, b) Bigint *a, *b;
2822fe8fb19SBen Gras #else
2832fe8fb19SBen Gras 	(Bigint *a, Bigint *b)
2842fe8fb19SBen Gras #endif
2852fe8fb19SBen Gras {
2862fe8fb19SBen Gras 	Bigint *c;
2872fe8fb19SBen Gras 	int k, wa, wb, wc;
2882fe8fb19SBen Gras 	ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
2892fe8fb19SBen Gras 	ULong y;
2902fe8fb19SBen Gras #ifdef ULLong
2912fe8fb19SBen Gras 	ULLong carry, z;
2922fe8fb19SBen Gras #else
2932fe8fb19SBen Gras 	ULong carry, z;
2942fe8fb19SBen Gras #ifdef Pack_32
2952fe8fb19SBen Gras 	ULong z2;
2962fe8fb19SBen Gras #endif
2972fe8fb19SBen Gras #endif
2982fe8fb19SBen Gras 
2992fe8fb19SBen Gras 	if (a->wds < b->wds) {
3002fe8fb19SBen Gras 		c = a;
3012fe8fb19SBen Gras 		a = b;
3022fe8fb19SBen Gras 		b = c;
3032fe8fb19SBen Gras 		}
3042fe8fb19SBen Gras 	k = a->k;
3052fe8fb19SBen Gras 	wa = a->wds;
3062fe8fb19SBen Gras 	wb = b->wds;
3072fe8fb19SBen Gras 	wc = wa + wb;
3082fe8fb19SBen Gras 	if (wc > a->maxwds)
3092fe8fb19SBen Gras 		k++;
3102fe8fb19SBen Gras 	c = Balloc(k);
3112fe8fb19SBen Gras 	if (c == NULL)
3122fe8fb19SBen Gras 		return NULL;
3132fe8fb19SBen Gras 	for(x = c->x, xa = x + wc; x < xa; x++)
3142fe8fb19SBen Gras 		*x = 0;
3152fe8fb19SBen Gras 	xa = a->x;
3162fe8fb19SBen Gras 	xae = xa + wa;
3172fe8fb19SBen Gras 	xb = b->x;
3182fe8fb19SBen Gras 	xbe = xb + wb;
3192fe8fb19SBen Gras 	xc0 = c->x;
3202fe8fb19SBen Gras #ifdef ULLong
3212fe8fb19SBen Gras 	for(; xb < xbe; xc0++) {
3222fe8fb19SBen Gras 		if ( (y = *xb++) !=0) {
3232fe8fb19SBen Gras 			x = xa;
3242fe8fb19SBen Gras 			xc = xc0;
3252fe8fb19SBen Gras 			carry = 0;
3262fe8fb19SBen Gras 			do {
3272fe8fb19SBen Gras 				z = *x++ * (ULLong)y + *xc + carry;
3282fe8fb19SBen Gras 				carry = z >> 32;
3292fe8fb19SBen Gras 				/* LINTED conversion */
3302fe8fb19SBen Gras 				*xc++ = z & 0xffffffffUL;
3312fe8fb19SBen Gras 				}
3322fe8fb19SBen Gras 				while(x < xae);
3332fe8fb19SBen Gras 			/* LINTED conversion */
3342fe8fb19SBen Gras 			*xc = carry;
3352fe8fb19SBen Gras 			}
3362fe8fb19SBen Gras 		}
3372fe8fb19SBen Gras #else
3382fe8fb19SBen Gras #ifdef Pack_32
3392fe8fb19SBen Gras 	for(; xb < xbe; xb++, xc0++) {
3402fe8fb19SBen Gras 		if ( (y = *xb & 0xffff) !=0) {
3412fe8fb19SBen Gras 			x = xa;
3422fe8fb19SBen Gras 			xc = xc0;
3432fe8fb19SBen Gras 			carry = 0;
3442fe8fb19SBen Gras 			do {
3452fe8fb19SBen Gras 				z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
3462fe8fb19SBen Gras 				carry = z >> 16;
3472fe8fb19SBen Gras 				z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
3482fe8fb19SBen Gras 				carry = z2 >> 16;
3492fe8fb19SBen Gras 				Storeinc(xc, z2, z);
3502fe8fb19SBen Gras 				}
3512fe8fb19SBen Gras 				while(x < xae);
3522fe8fb19SBen Gras 			*xc = carry;
3532fe8fb19SBen Gras 			}
3542fe8fb19SBen Gras 		if ( (y = *xb >> 16) !=0) {
3552fe8fb19SBen Gras 			x = xa;
3562fe8fb19SBen Gras 			xc = xc0;
3572fe8fb19SBen Gras 			carry = 0;
3582fe8fb19SBen Gras 			z2 = *xc;
3592fe8fb19SBen Gras 			do {
3602fe8fb19SBen Gras 				z = (*x & 0xffff) * y + (*xc >> 16) + carry;
3612fe8fb19SBen Gras 				carry = z >> 16;
3622fe8fb19SBen Gras 				Storeinc(xc, z, z2);
3632fe8fb19SBen Gras 				z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
3642fe8fb19SBen Gras 				carry = z2 >> 16;
3652fe8fb19SBen Gras 				}
3662fe8fb19SBen Gras 				while(x < xae);
3672fe8fb19SBen Gras 			*xc = z2;
3682fe8fb19SBen Gras 			}
3692fe8fb19SBen Gras 		}
3702fe8fb19SBen Gras #else
3712fe8fb19SBen Gras 	for(; xb < xbe; xc0++) {
3722fe8fb19SBen Gras 		if ( (y = *xb++) !=0) {
3732fe8fb19SBen Gras 			x = xa;
3742fe8fb19SBen Gras 			xc = xc0;
3752fe8fb19SBen Gras 			carry = 0;
3762fe8fb19SBen Gras 			do {
3772fe8fb19SBen Gras 				z = *x++ * y + *xc + carry;
3782fe8fb19SBen Gras 				carry = z >> 16;
3792fe8fb19SBen Gras 				*xc++ = z & 0xffff;
3802fe8fb19SBen Gras 				}
3812fe8fb19SBen Gras 				while(x < xae);
3822fe8fb19SBen Gras 			*xc = carry;
3832fe8fb19SBen Gras 			}
3842fe8fb19SBen Gras 		}
3852fe8fb19SBen Gras #endif
3862fe8fb19SBen Gras #endif
3872fe8fb19SBen Gras 	for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
3882fe8fb19SBen Gras 	c->wds = wc;
3892fe8fb19SBen Gras 	return c;
3902fe8fb19SBen Gras 	}
3912fe8fb19SBen Gras 
3922fe8fb19SBen Gras  static Bigint *p5s;
3932fe8fb19SBen Gras 
3942fe8fb19SBen Gras  Bigint *
pow5mult(b,k)3952fe8fb19SBen Gras pow5mult
3962fe8fb19SBen Gras #ifdef KR_headers
3972fe8fb19SBen Gras 	(b, k) Bigint *b; int k;
3982fe8fb19SBen Gras #else
3992fe8fb19SBen Gras 	(Bigint *b, int k)
4002fe8fb19SBen Gras #endif
4012fe8fb19SBen Gras {
4022fe8fb19SBen Gras 	Bigint *b1, *p5, *p51;
4032fe8fb19SBen Gras 	int i;
4042fe8fb19SBen Gras 	static CONST int p05[3] = { 5, 25, 125 };
4052fe8fb19SBen Gras 
4062fe8fb19SBen Gras 	if ( (i = k & 3) !=0) {
4072fe8fb19SBen Gras 		b = multadd(b, p05[i-1], 0);
4082fe8fb19SBen Gras 		if (b == NULL)
4092fe8fb19SBen Gras 			return NULL;
4102fe8fb19SBen Gras 		}
4112fe8fb19SBen Gras 
4122fe8fb19SBen Gras 	if (!(k = (unsigned int)k >> 2))
4132fe8fb19SBen Gras 		return b;
4142fe8fb19SBen Gras 	if ((p5 = p5s) == 0) {
4152fe8fb19SBen Gras 		/* first time */
4162fe8fb19SBen Gras #ifdef MULTIPLE_THREADS
4172fe8fb19SBen Gras 		ACQUIRE_DTOA_LOCK(1);
4182fe8fb19SBen Gras 		if (!(p5 = p5s)) {
4192fe8fb19SBen Gras 			p5 = p5s = i2b(625);
420*f14fb602SLionel Sambuc 			if (p5 == NULL) {
421*f14fb602SLionel Sambuc 				FREE_DTOA_LOCK(1);
4222fe8fb19SBen Gras 				return NULL;
423*f14fb602SLionel Sambuc 			}
4242fe8fb19SBen Gras 			p5->next = 0;
4252fe8fb19SBen Gras 			}
4262fe8fb19SBen Gras 		FREE_DTOA_LOCK(1);
4272fe8fb19SBen Gras #else
4282fe8fb19SBen Gras 		p5 = p5s = i2b(625);
4292fe8fb19SBen Gras 		if (p5 == NULL)
4302fe8fb19SBen Gras 			return NULL;
4312fe8fb19SBen Gras 		p5->next = 0;
4322fe8fb19SBen Gras #endif
4332fe8fb19SBen Gras 		}
4342fe8fb19SBen Gras 	for(;;) {
4352fe8fb19SBen Gras 		if (k & 1) {
4362fe8fb19SBen Gras 			b1 = mult(b, p5);
4372fe8fb19SBen Gras 			if (b1 == NULL)
4382fe8fb19SBen Gras 				return NULL;
439*f14fb602SLionel Sambuc 			Bfree(b);
4402fe8fb19SBen Gras 			b = b1;
4412fe8fb19SBen Gras 			}
4422fe8fb19SBen Gras 		if (!(k = (unsigned int)k >> 1))
4432fe8fb19SBen Gras 			break;
4442fe8fb19SBen Gras 		if ((p51 = p5->next) == 0) {
4452fe8fb19SBen Gras #ifdef MULTIPLE_THREADS
4462fe8fb19SBen Gras 			ACQUIRE_DTOA_LOCK(1);
4472fe8fb19SBen Gras 			if (!(p51 = p5->next)) {
4482fe8fb19SBen Gras 				p51 = p5->next = mult(p5,p5);
449*f14fb602SLionel Sambuc 				if (p51 == NULL) {
450*f14fb602SLionel Sambuc 					FREE_DTOA_LOCK(1);
4512fe8fb19SBen Gras 					return NULL;
452*f14fb602SLionel Sambuc 				}
4532fe8fb19SBen Gras 				p51->next = 0;
4542fe8fb19SBen Gras 				}
4552fe8fb19SBen Gras 			FREE_DTOA_LOCK(1);
4562fe8fb19SBen Gras #else
4572fe8fb19SBen Gras 			p51 = p5->next = mult(p5,p5);
4582fe8fb19SBen Gras 			if (p51 == NULL)
4592fe8fb19SBen Gras 				return NULL;
4602fe8fb19SBen Gras 			p51->next = 0;
4612fe8fb19SBen Gras #endif
4622fe8fb19SBen Gras 			}
4632fe8fb19SBen Gras 		p5 = p51;
4642fe8fb19SBen Gras 		}
4652fe8fb19SBen Gras 	return b;
4662fe8fb19SBen Gras 	}
4672fe8fb19SBen Gras 
4682fe8fb19SBen Gras  Bigint *
lshift(b,k)4692fe8fb19SBen Gras lshift
4702fe8fb19SBen Gras #ifdef KR_headers
4712fe8fb19SBen Gras 	(b, k) Bigint *b; int k;
4722fe8fb19SBen Gras #else
4732fe8fb19SBen Gras 	(Bigint *b, int k)
4742fe8fb19SBen Gras #endif
4752fe8fb19SBen Gras {
4762fe8fb19SBen Gras 	int i, k1, n, n1;
4772fe8fb19SBen Gras 	Bigint *b1;
4782fe8fb19SBen Gras 	ULong *x, *x1, *xe, z;
4792fe8fb19SBen Gras 
4802fe8fb19SBen Gras 	n = (unsigned int)k >> kshift;
4812fe8fb19SBen Gras 	k1 = b->k;
4822fe8fb19SBen Gras 	n1 = n + b->wds + 1;
4832fe8fb19SBen Gras 	for(i = b->maxwds; n1 > i; i <<= 1)
4842fe8fb19SBen Gras 		k1++;
4852fe8fb19SBen Gras 	b1 = Balloc(k1);
4862fe8fb19SBen Gras 	if (b1 == NULL)
4872fe8fb19SBen Gras 		return NULL;
4882fe8fb19SBen Gras 	x1 = b1->x;
4892fe8fb19SBen Gras 	for(i = 0; i < n; i++)
4902fe8fb19SBen Gras 		*x1++ = 0;
4912fe8fb19SBen Gras 	x = b->x;
4922fe8fb19SBen Gras 	xe = x + b->wds;
4932fe8fb19SBen Gras 	if (k &= kmask) {
4942fe8fb19SBen Gras #ifdef Pack_32
4952fe8fb19SBen Gras 		k1 = 32 - k;
4962fe8fb19SBen Gras 		z = 0;
4972fe8fb19SBen Gras 		do {
4982fe8fb19SBen Gras 			*x1++ = *x << k | z;
4992fe8fb19SBen Gras 			z = *x++ >> k1;
5002fe8fb19SBen Gras 			}
5012fe8fb19SBen Gras 			while(x < xe);
5022fe8fb19SBen Gras 		if ((*x1 = z) !=0)
5032fe8fb19SBen Gras 			++n1;
5042fe8fb19SBen Gras #else
5052fe8fb19SBen Gras 		k1 = 16 - k;
5062fe8fb19SBen Gras 		z = 0;
5072fe8fb19SBen Gras 		do {
5082fe8fb19SBen Gras 			*x1++ = *x << k  & 0xffff | z;
5092fe8fb19SBen Gras 			z = *x++ >> k1;
5102fe8fb19SBen Gras 			}
5112fe8fb19SBen Gras 			while(x < xe);
5122fe8fb19SBen Gras 		if (*x1 = z)
5132fe8fb19SBen Gras 			++n1;
5142fe8fb19SBen Gras #endif
5152fe8fb19SBen Gras 		}
5162fe8fb19SBen Gras 	else do
5172fe8fb19SBen Gras 		*x1++ = *x++;
5182fe8fb19SBen Gras 		while(x < xe);
5192fe8fb19SBen Gras 	b1->wds = n1 - 1;
5202fe8fb19SBen Gras 	Bfree(b);
5212fe8fb19SBen Gras 	return b1;
5222fe8fb19SBen Gras 	}
5232fe8fb19SBen Gras 
5242fe8fb19SBen Gras  int
cmp(a,b)5252fe8fb19SBen Gras cmp
5262fe8fb19SBen Gras #ifdef KR_headers
5272fe8fb19SBen Gras 	(a, b) Bigint *a, *b;
5282fe8fb19SBen Gras #else
5292fe8fb19SBen Gras 	(Bigint *a, Bigint *b)
5302fe8fb19SBen Gras #endif
5312fe8fb19SBen Gras {
5322fe8fb19SBen Gras 	ULong *xa, *xa0, *xb, *xb0;
5332fe8fb19SBen Gras 	int i, j;
5342fe8fb19SBen Gras 
5352fe8fb19SBen Gras 	i = a->wds;
5362fe8fb19SBen Gras 	j = b->wds;
5372fe8fb19SBen Gras #ifdef DEBUG
5382fe8fb19SBen Gras 	if (i > 1 && !a->x[i-1])
5392fe8fb19SBen Gras 		Bug("cmp called with a->x[a->wds-1] == 0");
5402fe8fb19SBen Gras 	if (j > 1 && !b->x[j-1])
5412fe8fb19SBen Gras 		Bug("cmp called with b->x[b->wds-1] == 0");
5422fe8fb19SBen Gras #endif
5432fe8fb19SBen Gras 	if (i -= j)
5442fe8fb19SBen Gras 		return i;
5452fe8fb19SBen Gras 	xa0 = a->x;
5462fe8fb19SBen Gras 	xa = xa0 + j;
5472fe8fb19SBen Gras 	xb0 = b->x;
5482fe8fb19SBen Gras 	xb = xb0 + j;
5492fe8fb19SBen Gras 	for(;;) {
5502fe8fb19SBen Gras 		if (*--xa != *--xb)
5512fe8fb19SBen Gras 			return *xa < *xb ? -1 : 1;
5522fe8fb19SBen Gras 		if (xa <= xa0)
5532fe8fb19SBen Gras 			break;
5542fe8fb19SBen Gras 		}
5552fe8fb19SBen Gras 	return 0;
5562fe8fb19SBen Gras 	}
5572fe8fb19SBen Gras 
5582fe8fb19SBen Gras  Bigint *
diff(a,b)5592fe8fb19SBen Gras diff
5602fe8fb19SBen Gras #ifdef KR_headers
5612fe8fb19SBen Gras 	(a, b) Bigint *a, *b;
5622fe8fb19SBen Gras #else
5632fe8fb19SBen Gras 	(Bigint *a, Bigint *b)
5642fe8fb19SBen Gras #endif
5652fe8fb19SBen Gras {
5662fe8fb19SBen Gras 	Bigint *c;
5672fe8fb19SBen Gras 	int i, wa, wb;
5682fe8fb19SBen Gras 	ULong *xa, *xae, *xb, *xbe, *xc;
5692fe8fb19SBen Gras #ifdef ULLong
5702fe8fb19SBen Gras 	ULLong borrow, y;
5712fe8fb19SBen Gras #else
5722fe8fb19SBen Gras 	ULong borrow, y;
5732fe8fb19SBen Gras #ifdef Pack_32
5742fe8fb19SBen Gras 	ULong z;
5752fe8fb19SBen Gras #endif
5762fe8fb19SBen Gras #endif
5772fe8fb19SBen Gras 
5782fe8fb19SBen Gras 	i = cmp(a,b);
5792fe8fb19SBen Gras 	if (!i) {
5802fe8fb19SBen Gras 		c = Balloc(0);
5812fe8fb19SBen Gras 		if (c == NULL)
5822fe8fb19SBen Gras 			return NULL;
5832fe8fb19SBen Gras 		c->wds = 1;
5842fe8fb19SBen Gras 		c->x[0] = 0;
5852fe8fb19SBen Gras 		return c;
5862fe8fb19SBen Gras 		}
5872fe8fb19SBen Gras 	if (i < 0) {
5882fe8fb19SBen Gras 		c = a;
5892fe8fb19SBen Gras 		a = b;
5902fe8fb19SBen Gras 		b = c;
5912fe8fb19SBen Gras 		i = 1;
5922fe8fb19SBen Gras 		}
5932fe8fb19SBen Gras 	else
5942fe8fb19SBen Gras 		i = 0;
5952fe8fb19SBen Gras 	c = Balloc(a->k);
5962fe8fb19SBen Gras 	if (c == NULL)
5972fe8fb19SBen Gras 		return NULL;
5982fe8fb19SBen Gras 	c->sign = i;
5992fe8fb19SBen Gras 	wa = a->wds;
6002fe8fb19SBen Gras 	xa = a->x;
6012fe8fb19SBen Gras 	xae = xa + wa;
6022fe8fb19SBen Gras 	wb = b->wds;
6032fe8fb19SBen Gras 	xb = b->x;
6042fe8fb19SBen Gras 	xbe = xb + wb;
6052fe8fb19SBen Gras 	xc = c->x;
6062fe8fb19SBen Gras 	borrow = 0;
6072fe8fb19SBen Gras #ifdef ULLong
6082fe8fb19SBen Gras 	do {
6092fe8fb19SBen Gras 		y = (ULLong)*xa++ - *xb++ - borrow;
6102fe8fb19SBen Gras 		borrow = y >> 32 & 1UL;
6112fe8fb19SBen Gras 		/* LINTED conversion */
6122fe8fb19SBen Gras 		*xc++ = y & 0xffffffffUL;
6132fe8fb19SBen Gras 		}
6142fe8fb19SBen Gras 		while(xb < xbe);
6152fe8fb19SBen Gras 	while(xa < xae) {
6162fe8fb19SBen Gras 		y = *xa++ - borrow;
6172fe8fb19SBen Gras 		borrow = y >> 32 & 1UL;
6182fe8fb19SBen Gras 		/* LINTED conversion */
6192fe8fb19SBen Gras 		*xc++ = y & 0xffffffffUL;
6202fe8fb19SBen Gras 		}
6212fe8fb19SBen Gras #else
6222fe8fb19SBen Gras #ifdef Pack_32
6232fe8fb19SBen Gras 	do {
6242fe8fb19SBen Gras 		y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
6252fe8fb19SBen Gras 		borrow = (y & 0x10000) >> 16;
6262fe8fb19SBen Gras 		z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
6272fe8fb19SBen Gras 		borrow = (z & 0x10000) >> 16;
6282fe8fb19SBen Gras 		Storeinc(xc, z, y);
6292fe8fb19SBen Gras 		}
6302fe8fb19SBen Gras 		while(xb < xbe);
6312fe8fb19SBen Gras 	while(xa < xae) {
6322fe8fb19SBen Gras 		y = (*xa & 0xffff) - borrow;
6332fe8fb19SBen Gras 		borrow = (y & 0x10000) >> 16;
6342fe8fb19SBen Gras 		z = (*xa++ >> 16) - borrow;
6352fe8fb19SBen Gras 		borrow = (z & 0x10000) >> 16;
6362fe8fb19SBen Gras 		Storeinc(xc, z, y);
6372fe8fb19SBen Gras 		}
6382fe8fb19SBen Gras #else
6392fe8fb19SBen Gras 	do {
6402fe8fb19SBen Gras 		y = *xa++ - *xb++ - borrow;
6412fe8fb19SBen Gras 		borrow = (y & 0x10000) >> 16;
6422fe8fb19SBen Gras 		*xc++ = y & 0xffff;
6432fe8fb19SBen Gras 		}
6442fe8fb19SBen Gras 		while(xb < xbe);
6452fe8fb19SBen Gras 	while(xa < xae) {
6462fe8fb19SBen Gras 		y = *xa++ - borrow;
6472fe8fb19SBen Gras 		borrow = (y & 0x10000) >> 16;
6482fe8fb19SBen Gras 		*xc++ = y & 0xffff;
6492fe8fb19SBen Gras 		}
6502fe8fb19SBen Gras #endif
6512fe8fb19SBen Gras #endif
6522fe8fb19SBen Gras 	while(!*--xc)
6532fe8fb19SBen Gras 		wa--;
6542fe8fb19SBen Gras 	c->wds = wa;
6552fe8fb19SBen Gras 	return c;
6562fe8fb19SBen Gras 	}
6572fe8fb19SBen Gras 
6582fe8fb19SBen Gras  double
b2d(a,e)6592fe8fb19SBen Gras b2d
6602fe8fb19SBen Gras #ifdef KR_headers
6612fe8fb19SBen Gras 	(a, e) Bigint *a; int *e;
6622fe8fb19SBen Gras #else
6632fe8fb19SBen Gras 	(Bigint *a, int *e)
6642fe8fb19SBen Gras #endif
6652fe8fb19SBen Gras {
6662fe8fb19SBen Gras 	ULong *xa, *xa0, w, y, z;
6672fe8fb19SBen Gras 	int k;
668*f14fb602SLionel Sambuc 	U d;
6692fe8fb19SBen Gras #ifdef VAX
6702fe8fb19SBen Gras 	ULong d0, d1;
6712fe8fb19SBen Gras #else
672*f14fb602SLionel Sambuc #define d0 word0(&d)
673*f14fb602SLionel Sambuc #define d1 word1(&d)
6742fe8fb19SBen Gras #endif
6752fe8fb19SBen Gras 
6762fe8fb19SBen Gras 	xa0 = a->x;
6772fe8fb19SBen Gras 	xa = xa0 + a->wds;
6782fe8fb19SBen Gras 	y = *--xa;
6792fe8fb19SBen Gras #ifdef DEBUG
6802fe8fb19SBen Gras 	if (!y) Bug("zero y in b2d");
6812fe8fb19SBen Gras #endif
6822fe8fb19SBen Gras 	k = hi0bits(y);
6832fe8fb19SBen Gras 	*e = 32 - k;
6842fe8fb19SBen Gras #ifdef Pack_32
6852fe8fb19SBen Gras 	if (k < Ebits) {
6862fe8fb19SBen Gras 		d0 = Exp_1 | y >> (Ebits - k);
6872fe8fb19SBen Gras 		w = xa > xa0 ? *--xa : 0;
6882fe8fb19SBen Gras 		d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
6892fe8fb19SBen Gras 		goto ret_d;
6902fe8fb19SBen Gras 		}
6912fe8fb19SBen Gras 	z = xa > xa0 ? *--xa : 0;
6922fe8fb19SBen Gras 	if (k -= Ebits) {
6932fe8fb19SBen Gras 		d0 = Exp_1 | y << k | z >> (32 - k);
6942fe8fb19SBen Gras 		y = xa > xa0 ? *--xa : 0;
6952fe8fb19SBen Gras 		d1 = z << k | y >> (32 - k);
6962fe8fb19SBen Gras 		}
6972fe8fb19SBen Gras 	else {
6982fe8fb19SBen Gras 		d0 = Exp_1 | y;
6992fe8fb19SBen Gras 		d1 = z;
7002fe8fb19SBen Gras 		}
7012fe8fb19SBen Gras #else
7022fe8fb19SBen Gras 	if (k < Ebits + 16) {
7032fe8fb19SBen Gras 		z = xa > xa0 ? *--xa : 0;
7042fe8fb19SBen Gras 		d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
7052fe8fb19SBen Gras 		w = xa > xa0 ? *--xa : 0;
7062fe8fb19SBen Gras 		y = xa > xa0 ? *--xa : 0;
7072fe8fb19SBen Gras 		d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
7082fe8fb19SBen Gras 		goto ret_d;
7092fe8fb19SBen Gras 		}
7102fe8fb19SBen Gras 	z = xa > xa0 ? *--xa : 0;
7112fe8fb19SBen Gras 	w = xa > xa0 ? *--xa : 0;
7122fe8fb19SBen Gras 	k -= Ebits + 16;
7132fe8fb19SBen Gras 	d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
7142fe8fb19SBen Gras 	y = xa > xa0 ? *--xa : 0;
7152fe8fb19SBen Gras 	d1 = w << k + 16 | y << k;
7162fe8fb19SBen Gras #endif
7172fe8fb19SBen Gras  ret_d:
7182fe8fb19SBen Gras #ifdef VAX
719*f14fb602SLionel Sambuc 	word0(&d) = d0 >> 16 | d0 << 16;
720*f14fb602SLionel Sambuc 	word1(&d) = d1 >> 16 | d1 << 16;
7212fe8fb19SBen Gras #endif
722*f14fb602SLionel Sambuc 	return dval(&d);
7232fe8fb19SBen Gras 	}
7242fe8fb19SBen Gras #undef d0
7252fe8fb19SBen Gras #undef d1
7262fe8fb19SBen Gras 
7272fe8fb19SBen Gras  Bigint *
d2b(dd,e,bits)7282fe8fb19SBen Gras d2b
7292fe8fb19SBen Gras #ifdef KR_headers
730*f14fb602SLionel Sambuc 	(dd, e, bits) double dd; int *e, *bits;
7312fe8fb19SBen Gras #else
732*f14fb602SLionel Sambuc 	(double dd, int *e, int *bits)
7332fe8fb19SBen Gras #endif
7342fe8fb19SBen Gras {
7352fe8fb19SBen Gras 	Bigint *b;
736*f14fb602SLionel Sambuc 	U d;
7372fe8fb19SBen Gras #ifndef Sudden_Underflow
7382fe8fb19SBen Gras 	int i;
7392fe8fb19SBen Gras #endif
7402fe8fb19SBen Gras 	int de, k;
7412fe8fb19SBen Gras 	ULong *x, y, z;
7422fe8fb19SBen Gras #ifdef VAX
7432fe8fb19SBen Gras 	ULong d0, d1;
7442fe8fb19SBen Gras #else
745*f14fb602SLionel Sambuc #define d0 word0(&d)
746*f14fb602SLionel Sambuc #define d1 word1(&d)
747*f14fb602SLionel Sambuc #endif
748*f14fb602SLionel Sambuc 	d.d = dd;
749*f14fb602SLionel Sambuc #ifdef VAX
750*f14fb602SLionel Sambuc 	d0 = word0(&d) >> 16 | word0(&d) << 16;
751*f14fb602SLionel Sambuc 	d1 = word1(&d) >> 16 | word1(&d) << 16;
7522fe8fb19SBen Gras #endif
7532fe8fb19SBen Gras 
7542fe8fb19SBen Gras #ifdef Pack_32
7552fe8fb19SBen Gras 	b = Balloc(1);
7562fe8fb19SBen Gras #else
7572fe8fb19SBen Gras 	b = Balloc(2);
7582fe8fb19SBen Gras #endif
7592fe8fb19SBen Gras 	if (b == NULL)
7602fe8fb19SBen Gras 		return NULL;
7612fe8fb19SBen Gras 	x = b->x;
7622fe8fb19SBen Gras 
7632fe8fb19SBen Gras 	z = d0 & Frac_mask;
7642fe8fb19SBen Gras 	d0 &= 0x7fffffff;	/* clear sign bit, which we ignore */
7652fe8fb19SBen Gras #ifdef Sudden_Underflow
7662fe8fb19SBen Gras 	de = (int)(d0 >> Exp_shift);
7672fe8fb19SBen Gras #ifndef IBM
7682fe8fb19SBen Gras 	z |= Exp_msk11;
7692fe8fb19SBen Gras #endif
7702fe8fb19SBen Gras #else
7712fe8fb19SBen Gras 	if ( (de = (int)(d0 >> Exp_shift)) !=0)
7722fe8fb19SBen Gras 		z |= Exp_msk1;
7732fe8fb19SBen Gras #endif
7742fe8fb19SBen Gras #ifdef Pack_32
7752fe8fb19SBen Gras 	if ( (y = d1) !=0) {
7762fe8fb19SBen Gras 		if ( (k = lo0bits(&y)) !=0) {
7772fe8fb19SBen Gras 			x[0] = y | z << (32 - k);
7782fe8fb19SBen Gras 			z >>= k;
7792fe8fb19SBen Gras 			}
7802fe8fb19SBen Gras 		else
7812fe8fb19SBen Gras 			x[0] = y;
7822fe8fb19SBen Gras #ifndef Sudden_Underflow
7832fe8fb19SBen Gras 		i =
7842fe8fb19SBen Gras #endif
7852fe8fb19SBen Gras 		     b->wds = (x[1] = z) !=0 ? 2 : 1;
7862fe8fb19SBen Gras 		}
7872fe8fb19SBen Gras 	else {
7882fe8fb19SBen Gras 		k = lo0bits(&z);
7892fe8fb19SBen Gras 		x[0] = z;
7902fe8fb19SBen Gras #ifndef Sudden_Underflow
7912fe8fb19SBen Gras 		i =
7922fe8fb19SBen Gras #endif
7932fe8fb19SBen Gras 		    b->wds = 1;
7942fe8fb19SBen Gras 		k += 32;
7952fe8fb19SBen Gras 		}
7962fe8fb19SBen Gras #else
7972fe8fb19SBen Gras 	if ( (y = d1) !=0) {
7982fe8fb19SBen Gras 		if ( (k = lo0bits(&y)) !=0)
7992fe8fb19SBen Gras 			if (k >= 16) {
8002fe8fb19SBen Gras 				x[0] = y | z << 32 - k & 0xffff;
8012fe8fb19SBen Gras 				x[1] = z >> k - 16 & 0xffff;
8022fe8fb19SBen Gras 				x[2] = z >> k;
8032fe8fb19SBen Gras 				i = 2;
8042fe8fb19SBen Gras 				}
8052fe8fb19SBen Gras 			else {
8062fe8fb19SBen Gras 				x[0] = y & 0xffff;
8072fe8fb19SBen Gras 				x[1] = y >> 16 | z << 16 - k & 0xffff;
8082fe8fb19SBen Gras 				x[2] = z >> k & 0xffff;
8092fe8fb19SBen Gras 				x[3] = z >> k+16;
8102fe8fb19SBen Gras 				i = 3;
8112fe8fb19SBen Gras 				}
8122fe8fb19SBen Gras 		else {
8132fe8fb19SBen Gras 			x[0] = y & 0xffff;
8142fe8fb19SBen Gras 			x[1] = y >> 16;
8152fe8fb19SBen Gras 			x[2] = z & 0xffff;
8162fe8fb19SBen Gras 			x[3] = z >> 16;
8172fe8fb19SBen Gras 			i = 3;
8182fe8fb19SBen Gras 			}
8192fe8fb19SBen Gras 		}
8202fe8fb19SBen Gras 	else {
8212fe8fb19SBen Gras #ifdef DEBUG
8222fe8fb19SBen Gras 		if (!z)
8232fe8fb19SBen Gras 			Bug("Zero passed to d2b");
8242fe8fb19SBen Gras #endif
8252fe8fb19SBen Gras 		k = lo0bits(&z);
8262fe8fb19SBen Gras 		if (k >= 16) {
8272fe8fb19SBen Gras 			x[0] = z;
8282fe8fb19SBen Gras 			i = 0;
8292fe8fb19SBen Gras 			}
8302fe8fb19SBen Gras 		else {
8312fe8fb19SBen Gras 			x[0] = z & 0xffff;
8322fe8fb19SBen Gras 			x[1] = z >> 16;
8332fe8fb19SBen Gras 			i = 1;
8342fe8fb19SBen Gras 			}
8352fe8fb19SBen Gras 		k += 32;
8362fe8fb19SBen Gras 		}
8372fe8fb19SBen Gras 	while(!x[i])
8382fe8fb19SBen Gras 		--i;
8392fe8fb19SBen Gras 	b->wds = i + 1;
8402fe8fb19SBen Gras #endif
8412fe8fb19SBen Gras #ifndef Sudden_Underflow
8422fe8fb19SBen Gras 	if (de) {
8432fe8fb19SBen Gras #endif
8442fe8fb19SBen Gras #ifdef IBM
8452fe8fb19SBen Gras 		*e = (de - Bias - (P-1) << 2) + k;
846*f14fb602SLionel Sambuc 		*bits = 4*P + 8 - k - hi0bits(word0(&d) & Frac_mask);
8472fe8fb19SBen Gras #else
8482fe8fb19SBen Gras 		*e = de - Bias - (P-1) + k;
8492fe8fb19SBen Gras 		*bits = P - k;
8502fe8fb19SBen Gras #endif
8512fe8fb19SBen Gras #ifndef Sudden_Underflow
8522fe8fb19SBen Gras 		}
8532fe8fb19SBen Gras 	else {
8542fe8fb19SBen Gras 		*e = de - Bias - (P-1) + 1 + k;
8552fe8fb19SBen Gras #ifdef Pack_32
8562fe8fb19SBen Gras 		*bits = 32*i - hi0bits(x[i-1]);
8572fe8fb19SBen Gras #else
8582fe8fb19SBen Gras 		*bits = (i+2)*16 - hi0bits(x[i]);
8592fe8fb19SBen Gras #endif
8602fe8fb19SBen Gras 		}
8612fe8fb19SBen Gras #endif
8622fe8fb19SBen Gras 	return b;
8632fe8fb19SBen Gras 	}
8642fe8fb19SBen Gras #undef d0
8652fe8fb19SBen Gras #undef d1
8662fe8fb19SBen Gras 
8672fe8fb19SBen Gras  CONST double
8682fe8fb19SBen Gras #ifdef IEEE_Arith
8692fe8fb19SBen Gras bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
8702fe8fb19SBen Gras CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
8712fe8fb19SBen Gras 		};
8722fe8fb19SBen Gras #else
8732fe8fb19SBen Gras #ifdef IBM
8742fe8fb19SBen Gras bigtens[] = { 1e16, 1e32, 1e64 };
8752fe8fb19SBen Gras CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
8762fe8fb19SBen Gras #else
8772fe8fb19SBen Gras bigtens[] = { 1e16, 1e32 };
8782fe8fb19SBen Gras CONST double tinytens[] = { 1e-16, 1e-32 };
8792fe8fb19SBen Gras #endif
8802fe8fb19SBen Gras #endif
8812fe8fb19SBen Gras 
8822fe8fb19SBen Gras  CONST double
8832fe8fb19SBen Gras tens[] = {
8842fe8fb19SBen Gras 		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
8852fe8fb19SBen Gras 		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
8862fe8fb19SBen Gras 		1e20, 1e21, 1e22
8872fe8fb19SBen Gras #ifdef VAX
8882fe8fb19SBen Gras 		, 1e23, 1e24
8892fe8fb19SBen Gras #endif
8902fe8fb19SBen Gras 		};
8912fe8fb19SBen Gras 
8922fe8fb19SBen Gras  char *
8932fe8fb19SBen Gras #ifdef KR_headers
strcp_D2A(a,b)8942fe8fb19SBen Gras strcp_D2A(a, b) char *a; char *b;
8952fe8fb19SBen Gras #else
8962fe8fb19SBen Gras strcp_D2A(char *a, CONST char *b)
8972fe8fb19SBen Gras #endif
8982fe8fb19SBen Gras {
8992fe8fb19SBen Gras 	while((*a = *b++))
9002fe8fb19SBen Gras 		a++;
9012fe8fb19SBen Gras 	return a;
9022fe8fb19SBen Gras 	}
9032fe8fb19SBen Gras 
9042fe8fb19SBen Gras #ifdef NO_STRING_H
9052fe8fb19SBen Gras 
9062fe8fb19SBen Gras  Char *
9072fe8fb19SBen Gras #ifdef KR_headers
memcpy_D2A(a,b,len)9082fe8fb19SBen Gras memcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
9092fe8fb19SBen Gras #else
9102fe8fb19SBen Gras memcpy_D2A(void *a1, void *b1, size_t len)
9112fe8fb19SBen Gras #endif
9122fe8fb19SBen Gras {
9132fe8fb19SBen Gras 	char *a = (char*)a1, *ae = a + len;
9142fe8fb19SBen Gras 	char *b = (char*)b1, *a0 = a;
9152fe8fb19SBen Gras 	while(a < ae)
9162fe8fb19SBen Gras 		*a++ = *b++;
9172fe8fb19SBen Gras 	return a0;
9182fe8fb19SBen Gras 	}
9192fe8fb19SBen Gras 
9202fe8fb19SBen Gras #endif /* NO_STRING_H */
921