Merge branch 'vendor/MDOCML'
[dragonfly.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 #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 */