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