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