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