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