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