]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - contrib/gdtoa/misc.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / contrib / gdtoa / misc.c
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 */