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