diff options
Diffstat (limited to 'src/lib/libc/stdlib/strtod.c')
| -rw-r--r-- | src/lib/libc/stdlib/strtod.c | 522 |
1 files changed, 241 insertions, 281 deletions
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c index b13fa128f5..4dc3d65a26 100644 --- a/src/lib/libc/stdlib/strtod.c +++ b/src/lib/libc/stdlib/strtod.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | /* $OpenBSD: strtod.c,v 1.30 2006/10/30 18:30:52 deraadt Exp $ */ | ||
| 1 | /**************************************************************** | 2 | /**************************************************************** |
| 2 | * | 3 | * |
| 3 | * The author of this software is David M. Gay. | 4 | * The author of this software is David M. Gay. |
| @@ -79,7 +80,6 @@ | |||
| 79 | * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision | 80 | * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision |
| 80 | * integer arithmetic. Whether this speeds things up or slows things | 81 | * integer arithmetic. Whether this speeds things up or slows things |
| 81 | * down depends on the machine and the number being converted. | 82 | * down depends on the machine and the number being converted. |
| 82 | * #define KR_headers for old-style C function headers. | ||
| 83 | * #define Bad_float_h if your system lacks a float.h or if it does not | 83 | * #define Bad_float_h if your system lacks a float.h or if it does not |
| 84 | * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, | 84 | * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, |
| 85 | * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. | 85 | * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. |
| @@ -89,13 +89,14 @@ | |||
| 89 | * directly -- and assumed always to succeed. | 89 | * directly -- and assumed always to succeed. |
| 90 | */ | 90 | */ |
| 91 | 91 | ||
| 92 | #if defined(LIBC_SCCS) && !defined(lint) | 92 | #include <sys/types.h> |
| 93 | static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; | ||
| 94 | #endif /* LIBC_SCCS and not lint */ | ||
| 95 | |||
| 96 | #if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ | 93 | #if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ |
| 97 | defined(__mips__) || defined(__ns32k__) || defined(__alpha__) | 94 | defined(__mips__) || defined(__mips64__) || defined(__ns32k__) || \ |
| 98 | #include <machine/endian.h> | 95 | defined(__alpha__) || defined(__powerpc__) || defined(__m88k__) || \ |
| 96 | defined(__hppa__) || defined(__amd64__) || defined(__sh__) || \ | ||
| 97 | defined(__sparc64__) || \ | ||
| 98 | (defined(__arm__) && defined(__VFP_FP__)) | ||
| 99 | |||
| 99 | #if BYTE_ORDER == BIG_ENDIAN | 100 | #if BYTE_ORDER == BIG_ENDIAN |
| 100 | #define IEEE_BIG_ENDIAN | 101 | #define IEEE_BIG_ENDIAN |
| 101 | #else | 102 | #else |
| @@ -103,7 +104,16 @@ static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $" | |||
| 103 | #endif | 104 | #endif |
| 104 | #endif | 105 | #endif |
| 105 | 106 | ||
| 106 | #ifdef vax | 107 | #if defined(__arm__) && !defined(__VFP_FP__) |
| 108 | /* | ||
| 109 | * Although the CPU is little endian the FP has different | ||
| 110 | * byte and word endianness. The byte order is still little endian | ||
| 111 | * but the word order is big endian. | ||
| 112 | */ | ||
| 113 | #define IEEE_BIG_ENDIAN | ||
| 114 | #endif | ||
| 115 | |||
| 116 | #ifdef __vax__ | ||
| 107 | #define VAX | 117 | #define VAX |
| 108 | #endif | 118 | #endif |
| 109 | 119 | ||
| @@ -115,26 +125,22 @@ static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $" | |||
| 115 | #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} | 125 | #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} |
| 116 | #endif | 126 | #endif |
| 117 | 127 | ||
| 128 | #include "thread_private.h" | ||
| 129 | |||
| 130 | _THREAD_PRIVATE_KEY(dtoa); | ||
| 131 | _THREAD_PRIVATE_KEY(pow5mult); | ||
| 132 | |||
| 118 | #ifdef __cplusplus | 133 | #ifdef __cplusplus |
| 119 | #include "malloc.h" | 134 | #include "malloc.h" |
| 120 | #include "memory.h" | 135 | #include "memory.h" |
| 121 | #else | 136 | #else |
| 122 | #ifndef KR_headers | ||
| 123 | #include "stdlib.h" | 137 | #include "stdlib.h" |
| 124 | #include "string.h" | 138 | #include "string.h" |
| 125 | #include "locale.h" | 139 | #include "locale.h" |
| 126 | #else | ||
| 127 | #include "malloc.h" | ||
| 128 | #include "memory.h" | ||
| 129 | #endif | ||
| 130 | #endif | 140 | #endif |
| 131 | 141 | ||
| 132 | #ifdef MALLOC | 142 | #ifdef MALLOC |
| 133 | #ifdef KR_headers | ||
| 134 | extern char *MALLOC(); | ||
| 135 | #else | ||
| 136 | extern void *MALLOC(size_t); | 143 | extern void *MALLOC(size_t); |
| 137 | #endif | ||
| 138 | #else | 144 | #else |
| 139 | #define MALLOC malloc | 145 | #define MALLOC malloc |
| 140 | #endif | 146 | #endif |
| @@ -143,7 +149,6 @@ extern void *MALLOC(size_t); | |||
| 143 | #include "errno.h" | 149 | #include "errno.h" |
| 144 | 150 | ||
| 145 | #ifdef Bad_float_h | 151 | #ifdef Bad_float_h |
| 146 | #undef __STDC__ | ||
| 147 | #ifdef IEEE_BIG_ENDIAN | 152 | #ifdef IEEE_BIG_ENDIAN |
| 148 | #define IEEE_ARITHMETIC | 153 | #define IEEE_ARITHMETIC |
| 149 | #endif | 154 | #endif |
| @@ -193,12 +198,8 @@ extern "C" { | |||
| 193 | #endif | 198 | #endif |
| 194 | 199 | ||
| 195 | #ifndef CONST | 200 | #ifndef CONST |
| 196 | #ifdef KR_headers | ||
| 197 | #define CONST /* blank */ | ||
| 198 | #else | ||
| 199 | #define CONST const | 201 | #define CONST const |
| 200 | #endif | 202 | #endif |
| 201 | #endif | ||
| 202 | 203 | ||
| 203 | #ifdef Unsigned_Shifts | 204 | #ifdef Unsigned_Shifts |
| 204 | #define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; | 205 | #define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; |
| @@ -208,23 +209,27 @@ extern "C" { | |||
| 208 | 209 | ||
| 209 | #if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \ | 210 | #if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \ |
| 210 | defined(IBM) != 1 | 211 | defined(IBM) != 1 |
| 211 | Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or | 212 | #error Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or IBM should be defined. |
| 212 | IBM should be defined. | ||
| 213 | #endif | 213 | #endif |
| 214 | 214 | ||
| 215 | typedef union { | ||
| 216 | double d; | ||
| 217 | ULong ul[2]; | ||
| 218 | } _double; | ||
| 219 | #define value(x) ((x).d) | ||
| 215 | #ifdef IEEE_LITTLE_ENDIAN | 220 | #ifdef IEEE_LITTLE_ENDIAN |
| 216 | #define word0(x) ((ULong *)&x)[1] | 221 | #define word0(x) ((x).ul[1]) |
| 217 | #define word1(x) ((ULong *)&x)[0] | 222 | #define word1(x) ((x).ul[0]) |
| 218 | #else | 223 | #else |
| 219 | #define word0(x) ((ULong *)&x)[0] | 224 | #define word0(x) ((x).ul[0]) |
| 220 | #define word1(x) ((ULong *)&x)[1] | 225 | #define word1(x) ((x).ul[1]) |
| 221 | #endif | 226 | #endif |
| 222 | 227 | ||
| 223 | /* The following definition of Storeinc is appropriate for MIPS processors. | 228 | /* The following definition of Storeinc is appropriate for MIPS processors. |
| 224 | * An alternative that might be better on some machines is | 229 | * An alternative that might be better on some machines is |
| 225 | * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) | 230 | * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) |
| 226 | */ | 231 | */ |
| 227 | #if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) | 232 | #if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__) |
| 228 | #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ | 233 | #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ |
| 229 | ((unsigned short *)a)[0] = (unsigned short)c, a++) | 234 | ((unsigned short *)a)[0] = (unsigned short)c, a++) |
| 230 | #else | 235 | #else |
| @@ -326,11 +331,7 @@ IBM should be defined. | |||
| 326 | #ifdef RND_PRODQUOT | 331 | #ifdef RND_PRODQUOT |
| 327 | #define rounded_product(a,b) a = rnd_prod(a, b) | 332 | #define rounded_product(a,b) a = rnd_prod(a, b) |
| 328 | #define rounded_quotient(a,b) a = rnd_quot(a, b) | 333 | #define rounded_quotient(a,b) a = rnd_quot(a, b) |
| 329 | #ifdef KR_headers | ||
| 330 | extern double rnd_prod(), rnd_quot(); | ||
| 331 | #else | ||
| 332 | extern double rnd_prod(double, double), rnd_quot(double, double); | 334 | extern double rnd_prod(double, double), rnd_quot(double, double); |
| 333 | #endif | ||
| 334 | #else | 335 | #else |
| 335 | #define rounded_product(a,b) a *= b | 336 | #define rounded_product(a,b) a *= b |
| 336 | #define rounded_quotient(a,b) a /= b | 337 | #define rounded_quotient(a,b) a /= b |
| @@ -369,54 +370,94 @@ Bigint { | |||
| 369 | 370 | ||
| 370 | static Bigint *freelist[Kmax+1]; | 371 | static Bigint *freelist[Kmax+1]; |
| 371 | 372 | ||
| 373 | #define PRIVATE_MEM 2304 | ||
| 374 | #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) | ||
| 375 | static double private_mem[PRIVATE_mem], *pmem_next = private_mem; | ||
| 376 | |||
| 372 | static Bigint * | 377 | static Bigint * |
| 373 | Balloc | 378 | Balloc(int k) |
| 374 | #ifdef KR_headers | ||
| 375 | (k) int k; | ||
| 376 | #else | ||
| 377 | (int k) | ||
| 378 | #endif | ||
| 379 | { | 379 | { |
| 380 | int x; | 380 | int x; |
| 381 | unsigned int len; | ||
| 381 | Bigint *rv; | 382 | Bigint *rv; |
| 382 | 383 | ||
| 383 | if (rv = freelist[k]) { | 384 | _THREAD_PRIVATE_MUTEX_LOCK(dtoa); |
| 385 | if ((rv = freelist[k])) { | ||
| 384 | freelist[k] = rv->next; | 386 | freelist[k] = rv->next; |
| 385 | } | 387 | } |
| 386 | else { | 388 | else { |
| 387 | x = 1 << k; | 389 | x = 1 << k; |
| 388 | rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)); | 390 | len = (sizeof(Bigint) + (x-1)*sizeof(Long) + sizeof(double) - 1) |
| 391 | /sizeof(double); | ||
| 392 | if (pmem_next - private_mem + len <= PRIVATE_mem) { | ||
| 393 | rv = (Bigint *)pmem_next; | ||
| 394 | pmem_next += len; | ||
| 395 | } | ||
| 396 | else | ||
| 397 | rv = (Bigint *)MALLOC(len *sizeof(double)); | ||
| 389 | rv->k = k; | 398 | rv->k = k; |
| 390 | rv->maxwds = x; | 399 | rv->maxwds = x; |
| 391 | } | 400 | } |
| 401 | _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa); | ||
| 392 | rv->sign = rv->wds = 0; | 402 | rv->sign = rv->wds = 0; |
| 393 | return rv; | 403 | return rv; |
| 394 | } | 404 | } |
| 395 | 405 | ||
| 396 | static void | 406 | static void |
| 397 | Bfree | 407 | Bfree(Bigint *v) |
| 398 | #ifdef KR_headers | ||
| 399 | (v) Bigint *v; | ||
| 400 | #else | ||
| 401 | (Bigint *v) | ||
| 402 | #endif | ||
| 403 | { | 408 | { |
| 404 | if (v) { | 409 | if (v) { |
| 410 | _THREAD_PRIVATE_MUTEX_LOCK(dtoa); | ||
| 405 | v->next = freelist[v->k]; | 411 | v->next = freelist[v->k]; |
| 406 | freelist[v->k] = v; | 412 | freelist[v->k] = v; |
| 413 | _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa); | ||
| 407 | } | 414 | } |
| 408 | } | 415 | } |
| 409 | 416 | ||
| 410 | #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ | 417 | #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ |
| 411 | y->wds*sizeof(Long) + 2*sizeof(int)) | 418 | y->wds*sizeof(Long) + 2*sizeof(int)) |
| 412 | 419 | ||
| 420 | /* return value is only used as a simple string, so mis-aligned parts | ||
| 421 | * inside the Bigint are not at risk on strict align architectures | ||
| 422 | */ | ||
| 423 | static char * | ||
| 424 | rv_alloc(int i) | ||
| 425 | { | ||
| 426 | int j, k, *r; | ||
| 427 | |||
| 428 | j = sizeof(ULong); | ||
| 429 | for(k = 0; | ||
| 430 | sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; | ||
| 431 | j <<= 1) | ||
| 432 | k++; | ||
| 433 | r = (int*)Balloc(k); | ||
| 434 | *r = k; | ||
| 435 | return (char *)(r+1); | ||
| 436 | } | ||
| 437 | |||
| 438 | static char * | ||
| 439 | nrv_alloc(char *s, char **rve, int n) | ||
| 440 | { | ||
| 441 | char *rv, *t; | ||
| 442 | |||
| 443 | t = rv = rv_alloc(n); | ||
| 444 | while((*t = *s++) !=0) | ||
| 445 | t++; | ||
| 446 | if (rve) | ||
| 447 | *rve = t; | ||
| 448 | return rv; | ||
| 449 | } | ||
| 450 | |||
| 451 | void | ||
| 452 | __freedtoa(char *s) | ||
| 453 | { | ||
| 454 | Bigint *b = (Bigint *)((int *)s - 1); | ||
| 455 | b->maxwds = 1 << (b->k = *(int*)b); | ||
| 456 | Bfree(b); | ||
| 457 | } | ||
| 458 | |||
| 413 | static Bigint * | 459 | static Bigint * |
| 414 | multadd | 460 | multadd(Bigint *b, int m, int a) /* multiply by m and add a */ |
| 415 | #ifdef KR_headers | ||
| 416 | (b, m, a) Bigint *b; int m, a; | ||
| 417 | #else | ||
| 418 | (Bigint *b, int m, int a) /* multiply by m and add a */ | ||
| 419 | #endif | ||
| 420 | { | 461 | { |
| 421 | int i, wds; | 462 | int i, wds; |
| 422 | ULong *x, y; | 463 | ULong *x, y; |
| @@ -456,12 +497,7 @@ multadd | |||
| 456 | } | 497 | } |
| 457 | 498 | ||
| 458 | static Bigint * | 499 | static Bigint * |
| 459 | s2b | 500 | s2b(CONST char *s, int nd0, int nd, ULong y9) |
| 460 | #ifdef KR_headers | ||
| 461 | (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; | ||
| 462 | #else | ||
| 463 | (CONST char *s, int nd0, int nd, ULong y9) | ||
| 464 | #endif | ||
| 465 | { | 501 | { |
| 466 | Bigint *b; | 502 | Bigint *b; |
| 467 | int i, k; | 503 | int i, k; |
| @@ -494,14 +530,9 @@ s2b | |||
| 494 | } | 530 | } |
| 495 | 531 | ||
| 496 | static int | 532 | static int |
| 497 | hi0bits | 533 | hi0bits(ULong x) |
| 498 | #ifdef KR_headers | ||
| 499 | (x) register ULong x; | ||
| 500 | #else | ||
| 501 | (register ULong x) | ||
| 502 | #endif | ||
| 503 | { | 534 | { |
| 504 | register int k = 0; | 535 | int k = 0; |
| 505 | 536 | ||
| 506 | if (!(x & 0xffff0000)) { | 537 | if (!(x & 0xffff0000)) { |
| 507 | k = 16; | 538 | k = 16; |
| @@ -528,15 +559,10 @@ hi0bits | |||
| 528 | } | 559 | } |
| 529 | 560 | ||
| 530 | static int | 561 | static int |
| 531 | lo0bits | 562 | lo0bits(ULong *y) |
| 532 | #ifdef KR_headers | ||
| 533 | (y) ULong *y; | ||
| 534 | #else | ||
| 535 | (ULong *y) | ||
| 536 | #endif | ||
| 537 | { | 563 | { |
| 538 | register int k; | 564 | int k; |
| 539 | register ULong x = *y; | 565 | ULong x = *y; |
| 540 | 566 | ||
| 541 | if (x & 7) { | 567 | if (x & 7) { |
| 542 | if (x & 1) | 568 | if (x & 1) |
| @@ -568,7 +594,7 @@ lo0bits | |||
| 568 | if (!(x & 1)) { | 594 | if (!(x & 1)) { |
| 569 | k++; | 595 | k++; |
| 570 | x >>= 1; | 596 | x >>= 1; |
| 571 | if (!x & 1) | 597 | if (!(x & 1)) |
| 572 | return 32; | 598 | return 32; |
| 573 | } | 599 | } |
| 574 | *y = x; | 600 | *y = x; |
| @@ -576,12 +602,7 @@ lo0bits | |||
| 576 | } | 602 | } |
| 577 | 603 | ||
| 578 | static Bigint * | 604 | static Bigint * |
| 579 | i2b | 605 | i2b(int i) |
| 580 | #ifdef KR_headers | ||
| 581 | (i) int i; | ||
| 582 | #else | ||
| 583 | (int i) | ||
| 584 | #endif | ||
| 585 | { | 606 | { |
| 586 | Bigint *b; | 607 | Bigint *b; |
| 587 | 608 | ||
| @@ -592,12 +613,7 @@ i2b | |||
| 592 | } | 613 | } |
| 593 | 614 | ||
| 594 | static Bigint * | 615 | static Bigint * |
| 595 | mult | 616 | mult(Bigint *a, Bigint *b) |
| 596 | #ifdef KR_headers | ||
| 597 | (a, b) Bigint *a, *b; | ||
| 598 | #else | ||
| 599 | (Bigint *a, Bigint *b) | ||
| 600 | #endif | ||
| 601 | { | 617 | { |
| 602 | Bigint *c; | 618 | Bigint *c; |
| 603 | int k, wa, wb, wc; | 619 | int k, wa, wb, wc; |
| @@ -628,7 +644,7 @@ mult | |||
| 628 | xc0 = c->x; | 644 | xc0 = c->x; |
| 629 | #ifdef Pack_32 | 645 | #ifdef Pack_32 |
| 630 | for(; xb < xbe; xb++, xc0++) { | 646 | for(; xb < xbe; xb++, xc0++) { |
| 631 | if (y = *xb & 0xffff) { | 647 | if ((y = *xb & 0xffff)) { |
| 632 | x = xa; | 648 | x = xa; |
| 633 | xc = xc0; | 649 | xc = xc0; |
| 634 | carry = 0; | 650 | carry = 0; |
| @@ -642,7 +658,7 @@ mult | |||
| 642 | while(x < xae); | 658 | while(x < xae); |
| 643 | *xc = carry; | 659 | *xc = carry; |
| 644 | } | 660 | } |
| 645 | if (y = *xb >> 16) { | 661 | if ((y = *xb >> 16)) { |
| 646 | x = xa; | 662 | x = xa; |
| 647 | xc = xc0; | 663 | xc = xc0; |
| 648 | carry = 0; | 664 | carry = 0; |
| @@ -682,26 +698,23 @@ mult | |||
| 682 | static Bigint *p5s; | 698 | static Bigint *p5s; |
| 683 | 699 | ||
| 684 | static Bigint * | 700 | static Bigint * |
| 685 | pow5mult | 701 | pow5mult(Bigint *b, int k) |
| 686 | #ifdef KR_headers | ||
| 687 | (b, k) Bigint *b; int k; | ||
| 688 | #else | ||
| 689 | (Bigint *b, int k) | ||
| 690 | #endif | ||
| 691 | { | 702 | { |
| 692 | Bigint *b1, *p5, *p51; | 703 | Bigint *b1, *p5, *p51; |
| 693 | int i; | 704 | int i; |
| 694 | static int p05[3] = { 5, 25, 125 }; | 705 | static int p05[3] = { 5, 25, 125 }; |
| 695 | 706 | ||
| 696 | if (i = k & 3) | 707 | if ((i = k & 3)) |
| 697 | b = multadd(b, p05[i-1], 0); | 708 | b = multadd(b, p05[i-1], 0); |
| 698 | 709 | ||
| 699 | if (!(k >>= 2)) | 710 | if (!(k >>= 2)) |
| 700 | return b; | 711 | return b; |
| 701 | if (!(p5 = p5s)) { | 712 | if (!(p5 = p5s)) { |
| 702 | /* first time */ | 713 | /* first time */ |
| 714 | _THREAD_PRIVATE_MUTEX_LOCK(pow5mult); | ||
| 703 | p5 = p5s = i2b(625); | 715 | p5 = p5s = i2b(625); |
| 704 | p5->next = 0; | 716 | p5->next = 0; |
| 717 | _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult); | ||
| 705 | } | 718 | } |
| 706 | for(;;) { | 719 | for(;;) { |
| 707 | if (k & 1) { | 720 | if (k & 1) { |
| @@ -712,8 +725,12 @@ pow5mult | |||
| 712 | if (!(k >>= 1)) | 725 | if (!(k >>= 1)) |
| 713 | break; | 726 | break; |
| 714 | if (!(p51 = p5->next)) { | 727 | if (!(p51 = p5->next)) { |
| 715 | p51 = p5->next = mult(p5,p5); | 728 | _THREAD_PRIVATE_MUTEX_LOCK(pow5mult); |
| 716 | p51->next = 0; | 729 | if (!(p51 = p5->next)) { |
| 730 | p51 = p5->next = mult(p5,p5); | ||
| 731 | p51->next = 0; | ||
| 732 | } | ||
| 733 | _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult); | ||
| 717 | } | 734 | } |
| 718 | p5 = p51; | 735 | p5 = p51; |
| 719 | } | 736 | } |
| @@ -721,12 +738,7 @@ pow5mult | |||
| 721 | } | 738 | } |
| 722 | 739 | ||
| 723 | static Bigint * | 740 | static Bigint * |
| 724 | lshift | 741 | lshift(Bigint *b, int k) |
| 725 | #ifdef KR_headers | ||
| 726 | (b, k) Bigint *b; int k; | ||
| 727 | #else | ||
| 728 | (Bigint *b, int k) | ||
| 729 | #endif | ||
| 730 | { | 742 | { |
| 731 | int i, k1, n, n1; | 743 | int i, k1, n, n1; |
| 732 | Bigint *b1; | 744 | Bigint *b1; |
| @@ -756,7 +768,7 @@ lshift | |||
| 756 | z = *x++ >> k1; | 768 | z = *x++ >> k1; |
| 757 | } | 769 | } |
| 758 | while(x < xe); | 770 | while(x < xe); |
| 759 | if (*x1 = z) | 771 | if ((*x1 = z)) |
| 760 | ++n1; | 772 | ++n1; |
| 761 | } | 773 | } |
| 762 | #else | 774 | #else |
| @@ -781,12 +793,7 @@ lshift | |||
| 781 | } | 793 | } |
| 782 | 794 | ||
| 783 | static int | 795 | static int |
| 784 | cmp | 796 | cmp(Bigint *a, Bigint *b) |
| 785 | #ifdef KR_headers | ||
| 786 | (a, b) Bigint *a, *b; | ||
| 787 | #else | ||
| 788 | (Bigint *a, Bigint *b) | ||
| 789 | #endif | ||
| 790 | { | 797 | { |
| 791 | ULong *xa, *xa0, *xb, *xb0; | 798 | ULong *xa, *xa0, *xb, *xb0; |
| 792 | int i, j; | 799 | int i, j; |
| @@ -815,12 +822,7 @@ cmp | |||
| 815 | } | 822 | } |
| 816 | 823 | ||
| 817 | static Bigint * | 824 | static Bigint * |
| 818 | diff | 825 | diff(Bigint *a, Bigint *b) |
| 819 | #ifdef KR_headers | ||
| 820 | (a, b) Bigint *a, *b; | ||
| 821 | #else | ||
| 822 | (Bigint *a, Bigint *b) | ||
| 823 | #endif | ||
| 824 | { | 826 | { |
| 825 | Bigint *c; | 827 | Bigint *c; |
| 826 | int i, wa, wb; | 828 | int i, wa, wb; |
| @@ -897,16 +899,13 @@ diff | |||
| 897 | } | 899 | } |
| 898 | 900 | ||
| 899 | static double | 901 | static double |
| 900 | ulp | 902 | ulp(double _x) |
| 901 | #ifdef KR_headers | ||
| 902 | (x) double x; | ||
| 903 | #else | ||
| 904 | (double x) | ||
| 905 | #endif | ||
| 906 | { | 903 | { |
| 907 | register Long L; | 904 | _double x; |
| 908 | double a; | 905 | Long L; |
| 906 | _double a; | ||
| 909 | 907 | ||
| 908 | value(x) = _x; | ||
| 910 | L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; | 909 | L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; |
| 911 | #ifndef Sudden_Underflow | 910 | #ifndef Sudden_Underflow |
| 912 | if (L > 0) { | 911 | if (L > 0) { |
| @@ -931,20 +930,15 @@ ulp | |||
| 931 | } | 930 | } |
| 932 | } | 931 | } |
| 933 | #endif | 932 | #endif |
| 934 | return a; | 933 | return value(a); |
| 935 | } | 934 | } |
| 936 | 935 | ||
| 937 | static double | 936 | static double |
| 938 | b2d | 937 | b2d(Bigint *a, int *e) |
| 939 | #ifdef KR_headers | ||
| 940 | (a, e) Bigint *a; int *e; | ||
| 941 | #else | ||
| 942 | (Bigint *a, int *e) | ||
| 943 | #endif | ||
| 944 | { | 938 | { |
| 945 | ULong *xa, *xa0, w, y, z; | 939 | ULong *xa, *xa0, w, y, z; |
| 946 | int k; | 940 | int k; |
| 947 | double d; | 941 | _double d; |
| 948 | #ifdef VAX | 942 | #ifdef VAX |
| 949 | ULong d0, d1; | 943 | ULong d0, d1; |
| 950 | #else | 944 | #else |
| @@ -1001,22 +995,22 @@ b2d | |||
| 1001 | #undef d0 | 995 | #undef d0 |
| 1002 | #undef d1 | 996 | #undef d1 |
| 1003 | #endif | 997 | #endif |
| 1004 | return d; | 998 | return value(d); |
| 1005 | } | 999 | } |
| 1006 | 1000 | ||
| 1007 | static Bigint * | 1001 | static Bigint * |
| 1008 | d2b | 1002 | d2b(double _d, int *e, int *bits) |
| 1009 | #ifdef KR_headers | ||
| 1010 | (d, e, bits) double d; int *e, *bits; | ||
| 1011 | #else | ||
| 1012 | (double d, int *e, int *bits) | ||
| 1013 | #endif | ||
| 1014 | { | 1003 | { |
| 1015 | Bigint *b; | 1004 | Bigint *b; |
| 1016 | int de, i, k; | 1005 | int de, i, k; |
| 1017 | ULong *x, y, z; | 1006 | ULong *x, y, z; |
| 1007 | _double d; | ||
| 1018 | #ifdef VAX | 1008 | #ifdef VAX |
| 1019 | ULong d0, d1; | 1009 | ULong d0, d1; |
| 1010 | #endif | ||
| 1011 | |||
| 1012 | value(d) = _d; | ||
| 1013 | #ifdef VAX | ||
| 1020 | d0 = word0(d) >> 16 | word0(d) << 16; | 1014 | d0 = word0(d) >> 16 | word0(d) << 16; |
| 1021 | d1 = word1(d) >> 16 | word1(d) << 16; | 1015 | d1 = word1(d) >> 16 | word1(d) << 16; |
| 1022 | #else | 1016 | #else |
| @@ -1134,18 +1128,13 @@ d2b | |||
| 1134 | #undef d1 | 1128 | #undef d1 |
| 1135 | 1129 | ||
| 1136 | static double | 1130 | static double |
| 1137 | ratio | 1131 | ratio(Bigint *a, Bigint *b) |
| 1138 | #ifdef KR_headers | ||
| 1139 | (a, b) Bigint *a, *b; | ||
| 1140 | #else | ||
| 1141 | (Bigint *a, Bigint *b) | ||
| 1142 | #endif | ||
| 1143 | { | 1132 | { |
| 1144 | double da, db; | 1133 | _double da, db; |
| 1145 | int k, ka, kb; | 1134 | int k, ka, kb; |
| 1146 | 1135 | ||
| 1147 | da = b2d(a, &ka); | 1136 | value(da) = b2d(a, &ka); |
| 1148 | db = b2d(b, &kb); | 1137 | value(db) = b2d(b, &kb); |
| 1149 | #ifdef Pack_32 | 1138 | #ifdef Pack_32 |
| 1150 | k = ka - kb + 32*(a->wds - b->wds); | 1139 | k = ka - kb + 32*(a->wds - b->wds); |
| 1151 | #else | 1140 | #else |
| @@ -1171,7 +1160,7 @@ ratio | |||
| 1171 | word0(db) += k*Exp_msk1; | 1160 | word0(db) += k*Exp_msk1; |
| 1172 | } | 1161 | } |
| 1173 | #endif | 1162 | #endif |
| 1174 | return da / db; | 1163 | return value(da) / value(db); |
| 1175 | } | 1164 | } |
| 1176 | 1165 | ||
| 1177 | static CONST double | 1166 | static CONST double |
| @@ -1201,32 +1190,29 @@ static CONST double tinytens[] = { 1e-16, 1e-32 }; | |||
| 1201 | #endif | 1190 | #endif |
| 1202 | 1191 | ||
| 1203 | double | 1192 | double |
| 1204 | strtod | 1193 | strtod(CONST char *s00, char **se) |
| 1205 | #ifdef KR_headers | ||
| 1206 | (s00, se) CONST char *s00; char **se; | ||
| 1207 | #else | ||
| 1208 | (CONST char *s00, char **se) | ||
| 1209 | #endif | ||
| 1210 | { | 1194 | { |
| 1211 | int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, | 1195 | int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, |
| 1212 | e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; | 1196 | e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; |
| 1213 | CONST char *s, *s0, *s1; | 1197 | CONST char *s, *s0, *s1; |
| 1214 | double aadj, aadj1, adj, rv, rv0; | 1198 | double aadj, aadj1, adj; |
| 1199 | /* | ||
| 1200 | * volatile forces mem update for FPUs where reg size != sizeof double, | ||
| 1201 | * which should trigger ERANGE in the case of underflow. | ||
| 1202 | */ | ||
| 1203 | volatile _double rv; | ||
| 1204 | _double rv0; | ||
| 1215 | Long L; | 1205 | Long L; |
| 1216 | ULong y, z; | 1206 | ULong y, z; |
| 1217 | Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; | 1207 | Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; |
| 1218 | 1208 | ||
| 1219 | #ifndef KR_headers | ||
| 1220 | CONST char decimal_point = localeconv()->decimal_point[0]; | 1209 | CONST char decimal_point = localeconv()->decimal_point[0]; |
| 1221 | #else | ||
| 1222 | CONST char decimal_point = '.'; | ||
| 1223 | #endif | ||
| 1224 | 1210 | ||
| 1225 | sign = nz0 = nz = 0; | 1211 | sign = nz0 = nz = 0; |
| 1226 | rv = 0.; | 1212 | value(rv) = 0.; |
| 1227 | 1213 | ||
| 1228 | 1214 | ||
| 1229 | for(s = s00; isspace(*s); s++) | 1215 | for(s = s00; isspace((unsigned char) *s); s++) |
| 1230 | ; | 1216 | ; |
| 1231 | 1217 | ||
| 1232 | if (*s == '-') { | 1218 | if (*s == '-') { |
| @@ -1340,9 +1326,9 @@ strtod | |||
| 1340 | if (!nd0) | 1326 | if (!nd0) |
| 1341 | nd0 = nd; | 1327 | nd0 = nd; |
| 1342 | k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; | 1328 | k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; |
| 1343 | rv = y; | 1329 | value(rv) = y; |
| 1344 | if (k > 9) | 1330 | if (k > 9) |
| 1345 | rv = tens[k - 9] * rv + z; | 1331 | value(rv) = tens[k - 9] * value(rv) + z; |
| 1346 | bd0 = 0; | 1332 | bd0 = 0; |
| 1347 | if (nd <= DBL_DIG | 1333 | if (nd <= DBL_DIG |
| 1348 | #ifndef RND_PRODQUOT | 1334 | #ifndef RND_PRODQUOT |
| @@ -1356,7 +1342,8 @@ strtod | |||
| 1356 | #ifdef VAX | 1342 | #ifdef VAX |
| 1357 | goto vax_ovfl_check; | 1343 | goto vax_ovfl_check; |
| 1358 | #else | 1344 | #else |
| 1359 | /* rv = */ rounded_product(rv, tens[e]); | 1345 | /* value(rv) = */ rounded_product(value(rv), |
| 1346 | tens[e]); | ||
| 1360 | goto ret; | 1347 | goto ret; |
| 1361 | #endif | 1348 | #endif |
| 1362 | } | 1349 | } |
| @@ -1366,27 +1353,30 @@ strtod | |||
| 1366 | * this for larger i values. | 1353 | * this for larger i values. |
| 1367 | */ | 1354 | */ |
| 1368 | e -= i; | 1355 | e -= i; |
| 1369 | rv *= tens[i]; | 1356 | value(rv) *= tens[i]; |
| 1370 | #ifdef VAX | 1357 | #ifdef VAX |
| 1371 | /* VAX exponent range is so narrow we must | 1358 | /* VAX exponent range is so narrow we must |
| 1372 | * worry about overflow here... | 1359 | * worry about overflow here... |
| 1373 | */ | 1360 | */ |
| 1374 | vax_ovfl_check: | 1361 | vax_ovfl_check: |
| 1375 | word0(rv) -= P*Exp_msk1; | 1362 | word0(rv) -= P*Exp_msk1; |
| 1376 | /* rv = */ rounded_product(rv, tens[e]); | 1363 | /* value(rv) = */ rounded_product(value(rv), |
| 1364 | tens[e]); | ||
| 1377 | if ((word0(rv) & Exp_mask) | 1365 | if ((word0(rv) & Exp_mask) |
| 1378 | > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) | 1366 | > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) |
| 1379 | goto ovfl; | 1367 | goto ovfl; |
| 1380 | word0(rv) += P*Exp_msk1; | 1368 | word0(rv) += P*Exp_msk1; |
| 1381 | #else | 1369 | #else |
| 1382 | /* rv = */ rounded_product(rv, tens[e]); | 1370 | /* value(rv) = */ rounded_product(value(rv), |
| 1371 | tens[e]); | ||
| 1383 | #endif | 1372 | #endif |
| 1384 | goto ret; | 1373 | goto ret; |
| 1385 | } | 1374 | } |
| 1386 | } | 1375 | } |
| 1387 | #ifndef Inaccurate_Divide | 1376 | #ifndef Inaccurate_Divide |
| 1388 | else if (e >= -Ten_pmax) { | 1377 | else if (e >= -Ten_pmax) { |
| 1389 | /* rv = */ rounded_quotient(rv, tens[-e]); | 1378 | /* value(rv) = */ rounded_quotient(value(rv), |
| 1379 | tens[-e]); | ||
| 1390 | goto ret; | 1380 | goto ret; |
| 1391 | } | 1381 | } |
| 1392 | #endif | 1382 | #endif |
| @@ -1397,13 +1387,13 @@ strtod | |||
| 1397 | 1387 | ||
| 1398 | if (e1 > 0) { | 1388 | if (e1 > 0) { |
| 1399 | if (i = e1 & 15) | 1389 | if (i = e1 & 15) |
| 1400 | rv *= tens[i]; | 1390 | value(rv) *= tens[i]; |
| 1401 | if (e1 &= ~15) { | 1391 | if (e1 &= ~15) { |
| 1402 | if (e1 > DBL_MAX_10_EXP) { | 1392 | if (e1 > DBL_MAX_10_EXP) { |
| 1403 | ovfl: | 1393 | ovfl: |
| 1404 | errno = ERANGE; | 1394 | errno = ERANGE; |
| 1405 | #ifdef __STDC__ | 1395 | #ifndef Bad_float_h |
| 1406 | rv = HUGE_VAL; | 1396 | value(rv) = HUGE_VAL; |
| 1407 | #else | 1397 | #else |
| 1408 | /* Can't trust HUGE_VAL */ | 1398 | /* Can't trust HUGE_VAL */ |
| 1409 | #ifdef IEEE_Arith | 1399 | #ifdef IEEE_Arith |
| @@ -1421,10 +1411,10 @@ strtod | |||
| 1421 | if (e1 >>= 4) { | 1411 | if (e1 >>= 4) { |
| 1422 | for(j = 0; e1 > 1; j++, e1 >>= 1) | 1412 | for(j = 0; e1 > 1; j++, e1 >>= 1) |
| 1423 | if (e1 & 1) | 1413 | if (e1 & 1) |
| 1424 | rv *= bigtens[j]; | 1414 | value(rv) *= bigtens[j]; |
| 1425 | /* The last multiplication could overflow. */ | 1415 | /* The last multiplication could overflow. */ |
| 1426 | word0(rv) -= P*Exp_msk1; | 1416 | word0(rv) -= P*Exp_msk1; |
| 1427 | rv *= bigtens[j]; | 1417 | value(rv) *= bigtens[j]; |
| 1428 | if ((z = word0(rv) & Exp_mask) | 1418 | if ((z = word0(rv) & Exp_mask) |
| 1429 | > Exp_msk1*(DBL_MAX_EXP+Bias-P)) | 1419 | > Exp_msk1*(DBL_MAX_EXP+Bias-P)) |
| 1430 | goto ovfl; | 1420 | goto ovfl; |
| @@ -1443,23 +1433,23 @@ strtod | |||
| 1443 | else if (e1 < 0) { | 1433 | else if (e1 < 0) { |
| 1444 | e1 = -e1; | 1434 | e1 = -e1; |
| 1445 | if (i = e1 & 15) | 1435 | if (i = e1 & 15) |
| 1446 | rv /= tens[i]; | 1436 | value(rv) /= tens[i]; |
| 1447 | if (e1 &= ~15) { | 1437 | if (e1 &= ~15) { |
| 1448 | e1 >>= 4; | 1438 | e1 >>= 4; |
| 1449 | if (e1 >= 1 << n_bigtens) | 1439 | if (e1 >= 1 << n_bigtens) |
| 1450 | goto undfl; | 1440 | goto undfl; |
| 1451 | for(j = 0; e1 > 1; j++, e1 >>= 1) | 1441 | for(j = 0; e1 > 1; j++, e1 >>= 1) |
| 1452 | if (e1 & 1) | 1442 | if (e1 & 1) |
| 1453 | rv *= tinytens[j]; | 1443 | value(rv) *= tinytens[j]; |
| 1454 | /* The last multiplication could underflow. */ | 1444 | /* The last multiplication could underflow. */ |
| 1455 | rv0 = rv; | 1445 | value(rv0) = value(rv); |
| 1456 | rv *= tinytens[j]; | 1446 | value(rv) *= tinytens[j]; |
| 1457 | if (!rv) { | 1447 | if (!value(rv)) { |
| 1458 | rv = 2.*rv0; | 1448 | value(rv) = 2.*value(rv0); |
| 1459 | rv *= tinytens[j]; | 1449 | value(rv) *= tinytens[j]; |
| 1460 | if (!rv) { | 1450 | if (!value(rv)) { |
| 1461 | undfl: | 1451 | undfl: |
| 1462 | rv = 0.; | 1452 | value(rv) = 0.; |
| 1463 | errno = ERANGE; | 1453 | errno = ERANGE; |
| 1464 | if (bd0) | 1454 | if (bd0) |
| 1465 | goto retfree; | 1455 | goto retfree; |
| @@ -1483,7 +1473,7 @@ strtod | |||
| 1483 | for(;;) { | 1473 | for(;;) { |
| 1484 | bd = Balloc(bd0->k); | 1474 | bd = Balloc(bd0->k); |
| 1485 | Bcopy(bd, bd0); | 1475 | Bcopy(bd, bd0); |
| 1486 | bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ | 1476 | bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ |
| 1487 | bs = i2b(1); | 1477 | bs = i2b(1); |
| 1488 | 1478 | ||
| 1489 | if (e >= 0) { | 1479 | if (e >= 0) { |
| @@ -1595,12 +1585,12 @@ strtod | |||
| 1595 | break; | 1585 | break; |
| 1596 | #endif | 1586 | #endif |
| 1597 | if (dsign) | 1587 | if (dsign) |
| 1598 | rv += ulp(rv); | 1588 | value(rv) += ulp(value(rv)); |
| 1599 | #ifndef ROUND_BIASED | 1589 | #ifndef ROUND_BIASED |
| 1600 | else { | 1590 | else { |
| 1601 | rv -= ulp(rv); | 1591 | value(rv) -= ulp(value(rv)); |
| 1602 | #ifndef Sudden_Underflow | 1592 | #ifndef Sudden_Underflow |
| 1603 | if (!rv) | 1593 | if (!value(rv)) |
| 1604 | goto undfl; | 1594 | goto undfl; |
| 1605 | #endif | 1595 | #endif |
| 1606 | } | 1596 | } |
| @@ -1651,10 +1641,10 @@ strtod | |||
| 1651 | /* Check for overflow */ | 1641 | /* Check for overflow */ |
| 1652 | 1642 | ||
| 1653 | if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { | 1643 | if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { |
| 1654 | rv0 = rv; | 1644 | value(rv0) = value(rv); |
| 1655 | word0(rv) -= P*Exp_msk1; | 1645 | word0(rv) -= P*Exp_msk1; |
| 1656 | adj = aadj1 * ulp(rv); | 1646 | adj = aadj1 * ulp(value(rv)); |
| 1657 | rv += adj; | 1647 | value(rv) += adj; |
| 1658 | if ((word0(rv) & Exp_mask) >= | 1648 | if ((word0(rv) & Exp_mask) >= |
| 1659 | Exp_msk1*(DBL_MAX_EXP+Bias-P)) { | 1649 | Exp_msk1*(DBL_MAX_EXP+Bias-P)) { |
| 1660 | if (word0(rv0) == Big0 && word1(rv0) == Big1) | 1650 | if (word0(rv0) == Big0 && word1(rv0) == Big1) |
| @@ -1669,10 +1659,10 @@ strtod | |||
| 1669 | else { | 1659 | else { |
| 1670 | #ifdef Sudden_Underflow | 1660 | #ifdef Sudden_Underflow |
| 1671 | if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { | 1661 | if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { |
| 1672 | rv0 = rv; | 1662 | value(rv0) = value(rv); |
| 1673 | word0(rv) += P*Exp_msk1; | 1663 | word0(rv) += P*Exp_msk1; |
| 1674 | adj = aadj1 * ulp(rv); | 1664 | adj = aadj1 * ulp(value(rv)); |
| 1675 | rv += adj; | 1665 | value(rv) += adj; |
| 1676 | #ifdef IBM | 1666 | #ifdef IBM |
| 1677 | if ((word0(rv) & Exp_mask) < P*Exp_msk1) | 1667 | if ((word0(rv) & Exp_mask) < P*Exp_msk1) |
| 1678 | #else | 1668 | #else |
| @@ -1690,8 +1680,8 @@ strtod | |||
| 1690 | word0(rv) -= P*Exp_msk1; | 1680 | word0(rv) -= P*Exp_msk1; |
| 1691 | } | 1681 | } |
| 1692 | else { | 1682 | else { |
| 1693 | adj = aadj1 * ulp(rv); | 1683 | adj = aadj1 * ulp(value(rv)); |
| 1694 | rv += adj; | 1684 | value(rv) += adj; |
| 1695 | } | 1685 | } |
| 1696 | #else | 1686 | #else |
| 1697 | /* Compute adj so that the IEEE rounding rules will | 1687 | /* Compute adj so that the IEEE rounding rules will |
| @@ -1706,8 +1696,8 @@ strtod | |||
| 1706 | if (!dsign) | 1696 | if (!dsign) |
| 1707 | aadj1 = -aadj1; | 1697 | aadj1 = -aadj1; |
| 1708 | } | 1698 | } |
| 1709 | adj = aadj1 * ulp(rv); | 1699 | adj = aadj1 * ulp(value(rv)); |
| 1710 | rv += adj; | 1700 | value(rv) += adj; |
| 1711 | #endif | 1701 | #endif |
| 1712 | } | 1702 | } |
| 1713 | z = word0(rv) & Exp_mask; | 1703 | z = word0(rv) & Exp_mask; |
| @@ -1738,16 +1728,11 @@ strtod | |||
| 1738 | ret: | 1728 | ret: |
| 1739 | if (se) | 1729 | if (se) |
| 1740 | *se = (char *)s; | 1730 | *se = (char *)s; |
| 1741 | return sign ? -rv : rv; | 1731 | return sign ? -value(rv) : value(rv); |
| 1742 | } | 1732 | } |
| 1743 | 1733 | ||
| 1744 | static int | 1734 | static int |
| 1745 | quorem | 1735 | quorem(Bigint *b, Bigint *S) |
| 1746 | #ifdef KR_headers | ||
| 1747 | (b, S) Bigint *b, *S; | ||
| 1748 | #else | ||
| 1749 | (Bigint *b, Bigint *S) | ||
| 1750 | #endif | ||
| 1751 | { | 1736 | { |
| 1752 | int n; | 1737 | int n; |
| 1753 | Long borrow, y; | 1738 | Long borrow, y; |
| @@ -1882,13 +1867,7 @@ quorem | |||
| 1882 | */ | 1867 | */ |
| 1883 | 1868 | ||
| 1884 | char * | 1869 | char * |
| 1885 | __dtoa | 1870 | __dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve) |
| 1886 | #ifdef KR_headers | ||
| 1887 | (d, mode, ndigits, decpt, sign, rve) | ||
| 1888 | double d; int mode, ndigits, *decpt, *sign; char **rve; | ||
| 1889 | #else | ||
| 1890 | (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) | ||
| 1891 | #endif | ||
| 1892 | { | 1871 | { |
| 1893 | /* Arguments ndigits, decpt, sign are similar to those | 1872 | /* Arguments ndigits, decpt, sign are similar to those |
| 1894 | of ecvt and fcvt; trailing zeros are suppressed from | 1873 | of ecvt and fcvt; trailing zeros are suppressed from |
| @@ -1933,17 +1912,11 @@ __dtoa | |||
| 1933 | ULong x; | 1912 | ULong x; |
| 1934 | #endif | 1913 | #endif |
| 1935 | Bigint *b, *b1, *delta, *mlo, *mhi, *S; | 1914 | Bigint *b, *b1, *delta, *mlo, *mhi, *S; |
| 1936 | double d2, ds, eps; | 1915 | double ds; |
| 1937 | char *s, *s0; | 1916 | char *s, *s0; |
| 1938 | static Bigint *result; | 1917 | _double d, d2, eps; |
| 1939 | static int result_k; | ||
| 1940 | 1918 | ||
| 1941 | if (result) { | 1919 | value(d) = _d; |
| 1942 | result->k = result_k; | ||
| 1943 | result->maxwds = 1 << result_k; | ||
| 1944 | Bfree(result); | ||
| 1945 | result = 0; | ||
| 1946 | } | ||
| 1947 | 1920 | ||
| 1948 | if (word0(d) & Sign_bit) { | 1921 | if (word0(d) & Sign_bit) { |
| 1949 | /* set sign for everything, including 0's and NaNs */ | 1922 | /* set sign for everything, including 0's and NaNs */ |
| @@ -1962,43 +1935,33 @@ __dtoa | |||
| 1962 | { | 1935 | { |
| 1963 | /* Infinity or NaN */ | 1936 | /* Infinity or NaN */ |
| 1964 | *decpt = 9999; | 1937 | *decpt = 9999; |
| 1965 | s = | ||
| 1966 | #ifdef IEEE_Arith | 1938 | #ifdef IEEE_Arith |
| 1967 | !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : | 1939 | if (!word1(d) && !(word0(d) & 0xfffff)) |
| 1940 | return nrv_alloc("Infinity", rve, 8); | ||
| 1968 | #endif | 1941 | #endif |
| 1969 | "NaN"; | 1942 | return nrv_alloc("NaN", rve, 3); |
| 1970 | if (rve) | ||
| 1971 | *rve = | ||
| 1972 | #ifdef IEEE_Arith | ||
| 1973 | s[3] ? s + 8 : | ||
| 1974 | #endif | ||
| 1975 | s + 3; | ||
| 1976 | return s; | ||
| 1977 | } | 1943 | } |
| 1978 | #endif | 1944 | #endif |
| 1979 | #ifdef IBM | 1945 | #ifdef IBM |
| 1980 | d += 0; /* normalize */ | 1946 | value(d) += 0; /* normalize */ |
| 1981 | #endif | 1947 | #endif |
| 1982 | if (!d) { | 1948 | if (!value(d)) { |
| 1983 | *decpt = 1; | 1949 | *decpt = 1; |
| 1984 | s = "0"; | 1950 | return nrv_alloc("0", rve, 1); |
| 1985 | if (rve) | ||
| 1986 | *rve = s + 1; | ||
| 1987 | return s; | ||
| 1988 | } | 1951 | } |
| 1989 | 1952 | ||
| 1990 | b = d2b(d, &be, &bbits); | 1953 | b = d2b(value(d), &be, &bbits); |
| 1991 | #ifdef Sudden_Underflow | 1954 | #ifdef Sudden_Underflow |
| 1992 | i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); | 1955 | i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); |
| 1993 | #else | 1956 | #else |
| 1994 | if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { | 1957 | if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { |
| 1995 | #endif | 1958 | #endif |
| 1996 | d2 = d; | 1959 | value(d2) = value(d); |
| 1997 | word0(d2) &= Frac_mask1; | 1960 | word0(d2) &= Frac_mask1; |
| 1998 | word0(d2) |= Exp_11; | 1961 | word0(d2) |= Exp_11; |
| 1999 | #ifdef IBM | 1962 | #ifdef IBM |
| 2000 | if (j = 11 - hi0bits(word0(d2) & Frac_mask)) | 1963 | if (j = 11 - hi0bits(word0(d2) & Frac_mask)) |
| 2001 | d2 /= 1 << j; | 1964 | value(d2) /= 1 << j; |
| 2002 | #endif | 1965 | #endif |
| 2003 | 1966 | ||
| 2004 | /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 | 1967 | /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 |
| @@ -2037,19 +2000,20 @@ __dtoa | |||
| 2037 | i = bbits + be + (Bias + (P-1) - 1); | 2000 | i = bbits + be + (Bias + (P-1) - 1); |
| 2038 | x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 | 2001 | x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 |
| 2039 | : word1(d) << 32 - i; | 2002 | : word1(d) << 32 - i; |
| 2040 | d2 = x; | 2003 | value(d2) = x; |
| 2041 | word0(d2) -= 31*Exp_msk1; /* adjust exponent */ | 2004 | word0(d2) -= 31*Exp_msk1; /* adjust exponent */ |
| 2042 | i -= (Bias + (P-1) - 1) + 1; | 2005 | i -= (Bias + (P-1) - 1) + 1; |
| 2043 | denorm = 1; | 2006 | denorm = 1; |
| 2044 | } | 2007 | } |
| 2045 | #endif | 2008 | #endif |
| 2046 | ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; | 2009 | ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 + |
| 2010 | i*0.301029995663981; | ||
| 2047 | k = (int)ds; | 2011 | k = (int)ds; |
| 2048 | if (ds < 0. && ds != k) | 2012 | if (ds < 0. && ds != k) |
| 2049 | k--; /* want k = floor(ds) */ | 2013 | k--; /* want k = floor(ds) */ |
| 2050 | k_check = 1; | 2014 | k_check = 1; |
| 2051 | if (k >= 0 && k <= Ten_pmax) { | 2015 | if (k >= 0 && k <= Ten_pmax) { |
| 2052 | if (d < tens[k]) | 2016 | if (value(d) < tens[k]) |
| 2053 | k--; | 2017 | k--; |
| 2054 | k_check = 0; | 2018 | k_check = 0; |
| 2055 | } | 2019 | } |
| @@ -2105,18 +2069,14 @@ __dtoa | |||
| 2105 | if (i <= 0) | 2069 | if (i <= 0) |
| 2106 | i = 1; | 2070 | i = 1; |
| 2107 | } | 2071 | } |
| 2108 | j = sizeof(ULong); | 2072 | s = s0 = rv_alloc(i); |
| 2109 | for(result_k = 0; sizeof(Bigint) - sizeof(ULong) + j <= i; | ||
| 2110 | j <<= 1) result_k++; | ||
| 2111 | result = Balloc(result_k); | ||
| 2112 | s = s0 = (char *)result; | ||
| 2113 | 2073 | ||
| 2114 | if (ilim >= 0 && ilim <= Quick_max && try_quick) { | 2074 | if (ilim >= 0 && ilim <= Quick_max && try_quick) { |
| 2115 | 2075 | ||
| 2116 | /* Try to get by with floating-point arithmetic. */ | 2076 | /* Try to get by with floating-point arithmetic. */ |
| 2117 | 2077 | ||
| 2118 | i = 0; | 2078 | i = 0; |
| 2119 | d2 = d; | 2079 | value(d2) = value(d); |
| 2120 | k0 = k; | 2080 | k0 = k; |
| 2121 | ilim0 = ilim; | 2081 | ilim0 = ilim; |
| 2122 | ieps = 2; /* conservative */ | 2082 | ieps = 2; /* conservative */ |
| @@ -2126,7 +2086,7 @@ __dtoa | |||
| 2126 | if (j & Bletch) { | 2086 | if (j & Bletch) { |
| 2127 | /* prevent overflows */ | 2087 | /* prevent overflows */ |
| 2128 | j &= Bletch - 1; | 2088 | j &= Bletch - 1; |
| 2129 | d /= bigtens[n_bigtens-1]; | 2089 | value(d) /= bigtens[n_bigtens-1]; |
| 2130 | ieps++; | 2090 | ieps++; |
| 2131 | } | 2091 | } |
| 2132 | for(; j; j >>= 1, i++) | 2092 | for(; j; j >>= 1, i++) |
| @@ -2134,32 +2094,32 @@ __dtoa | |||
| 2134 | ieps++; | 2094 | ieps++; |
| 2135 | ds *= bigtens[i]; | 2095 | ds *= bigtens[i]; |
| 2136 | } | 2096 | } |
| 2137 | d /= ds; | 2097 | value(d) /= ds; |
| 2138 | } | 2098 | } |
| 2139 | else if (j1 = -k) { | 2099 | else if (j1 = -k) { |
| 2140 | d *= tens[j1 & 0xf]; | 2100 | value(d) *= tens[j1 & 0xf]; |
| 2141 | for(j = j1 >> 4; j; j >>= 1, i++) | 2101 | for(j = j1 >> 4; j; j >>= 1, i++) |
| 2142 | if (j & 1) { | 2102 | if (j & 1) { |
| 2143 | ieps++; | 2103 | ieps++; |
| 2144 | d *= bigtens[i]; | 2104 | value(d) *= bigtens[i]; |
| 2145 | } | 2105 | } |
| 2146 | } | 2106 | } |
| 2147 | if (k_check && d < 1. && ilim > 0) { | 2107 | if (k_check && value(d) < 1. && ilim > 0) { |
| 2148 | if (ilim1 <= 0) | 2108 | if (ilim1 <= 0) |
| 2149 | goto fast_failed; | 2109 | goto fast_failed; |
| 2150 | ilim = ilim1; | 2110 | ilim = ilim1; |
| 2151 | k--; | 2111 | k--; |
| 2152 | d *= 10.; | 2112 | value(d) *= 10.; |
| 2153 | ieps++; | 2113 | ieps++; |
| 2154 | } | 2114 | } |
| 2155 | eps = ieps*d + 7.; | 2115 | value(eps) = ieps*value(d) + 7.; |
| 2156 | word0(eps) -= (P-1)*Exp_msk1; | 2116 | word0(eps) -= (P-1)*Exp_msk1; |
| 2157 | if (ilim == 0) { | 2117 | if (ilim == 0) { |
| 2158 | S = mhi = 0; | 2118 | S = mhi = 0; |
| 2159 | d -= 5.; | 2119 | value(d) -= 5.; |
| 2160 | if (d > eps) | 2120 | if (value(d) > value(eps)) |
| 2161 | goto one_digit; | 2121 | goto one_digit; |
| 2162 | if (d < -eps) | 2122 | if (value(d) < -value(eps)) |
| 2163 | goto no_digits; | 2123 | goto no_digits; |
| 2164 | goto fast_failed; | 2124 | goto fast_failed; |
| 2165 | } | 2125 | } |
| @@ -2168,33 +2128,33 @@ __dtoa | |||
| 2168 | /* Use Steele & White method of only | 2128 | /* Use Steele & White method of only |
| 2169 | * generating digits needed. | 2129 | * generating digits needed. |
| 2170 | */ | 2130 | */ |
| 2171 | eps = 0.5/tens[ilim-1] - eps; | 2131 | value(eps) = 0.5/tens[ilim-1] - value(eps); |
| 2172 | for(i = 0;;) { | 2132 | for(i = 0;;) { |
| 2173 | L = d; | 2133 | L = value(d); |
| 2174 | d -= L; | 2134 | value(d) -= L; |
| 2175 | *s++ = '0' + (int)L; | 2135 | *s++ = '0' + (int)L; |
| 2176 | if (d < eps) | 2136 | if (value(d) < value(eps)) |
| 2177 | goto ret1; | 2137 | goto ret1; |
| 2178 | if (1. - d < eps) | 2138 | if (1. - value(d) < value(eps)) |
| 2179 | goto bump_up; | 2139 | goto bump_up; |
| 2180 | if (++i >= ilim) | 2140 | if (++i >= ilim) |
| 2181 | break; | 2141 | break; |
| 2182 | eps *= 10.; | 2142 | value(eps) *= 10.; |
| 2183 | d *= 10.; | 2143 | value(d) *= 10.; |
| 2184 | } | 2144 | } |
| 2185 | } | 2145 | } |
| 2186 | else { | 2146 | else { |
| 2187 | #endif | 2147 | #endif |
| 2188 | /* Generate ilim digits, then fix them up. */ | 2148 | /* Generate ilim digits, then fix them up. */ |
| 2189 | eps *= tens[ilim-1]; | 2149 | value(eps) *= tens[ilim-1]; |
| 2190 | for(i = 1;; i++, d *= 10.) { | 2150 | for(i = 1;; i++, value(d) *= 10.) { |
| 2191 | L = d; | 2151 | L = value(d); |
| 2192 | d -= L; | 2152 | value(d) -= L; |
| 2193 | *s++ = '0' + (int)L; | 2153 | *s++ = '0' + (int)L; |
| 2194 | if (i == ilim) { | 2154 | if (i == ilim) { |
| 2195 | if (d > 0.5 + eps) | 2155 | if (value(d) > 0.5 + value(eps)) |
| 2196 | goto bump_up; | 2156 | goto bump_up; |
| 2197 | else if (d < 0.5 - eps) { | 2157 | else if (value(d) < 0.5 - value(eps)) { |
| 2198 | while(*--s == '0'); | 2158 | while(*--s == '0'); |
| 2199 | s++; | 2159 | s++; |
| 2200 | goto ret1; | 2160 | goto ret1; |
| @@ -2207,7 +2167,7 @@ __dtoa | |||
| 2207 | #endif | 2167 | #endif |
| 2208 | fast_failed: | 2168 | fast_failed: |
| 2209 | s = s0; | 2169 | s = s0; |
| 2210 | d = d2; | 2170 | value(d) = value(d2); |
| 2211 | k = k0; | 2171 | k = k0; |
| 2212 | ilim = ilim0; | 2172 | ilim = ilim0; |
| 2213 | } | 2173 | } |
| @@ -2219,24 +2179,24 @@ __dtoa | |||
| 2219 | ds = tens[k]; | 2179 | ds = tens[k]; |
| 2220 | if (ndigits < 0 && ilim <= 0) { | 2180 | if (ndigits < 0 && ilim <= 0) { |
| 2221 | S = mhi = 0; | 2181 | S = mhi = 0; |
| 2222 | if (ilim < 0 || d <= 5*ds) | 2182 | if (ilim < 0 || value(d) <= 5*ds) |
| 2223 | goto no_digits; | 2183 | goto no_digits; |
| 2224 | goto one_digit; | 2184 | goto one_digit; |
| 2225 | } | 2185 | } |
| 2226 | for(i = 1;; i++) { | 2186 | for(i = 1;; i++) { |
| 2227 | L = d / ds; | 2187 | L = value(d) / ds; |
| 2228 | d -= L*ds; | 2188 | value(d) -= L*ds; |
| 2229 | #ifdef Check_FLT_ROUNDS | 2189 | #ifdef Check_FLT_ROUNDS |
| 2230 | /* If FLT_ROUNDS == 2, L will usually be high by 1 */ | 2190 | /* If FLT_ROUNDS == 2, L will usually be high by 1 */ |
| 2231 | if (d < 0) { | 2191 | if (value(d) < 0) { |
| 2232 | L--; | 2192 | L--; |
| 2233 | d += ds; | 2193 | value(d) += ds; |
| 2234 | } | 2194 | } |
| 2235 | #endif | 2195 | #endif |
| 2236 | *s++ = '0' + (int)L; | 2196 | *s++ = '0' + (int)L; |
| 2237 | if (i == ilim) { | 2197 | if (i == ilim) { |
| 2238 | d += d; | 2198 | value(d) += value(d); |
| 2239 | if (d > ds || d == ds && L & 1) { | 2199 | if (value(d) > ds || value(d) == ds && L & 1) { |
| 2240 | bump_up: | 2200 | bump_up: |
| 2241 | while(*--s == '9') | 2201 | while(*--s == '9') |
| 2242 | if (s == s0) { | 2202 | if (s == s0) { |
| @@ -2248,7 +2208,7 @@ __dtoa | |||
| 2248 | } | 2208 | } |
| 2249 | break; | 2209 | break; |
| 2250 | } | 2210 | } |
| 2251 | if (!(d *= 10.)) | 2211 | if (!(value(d) *= 10.)) |
| 2252 | break; | 2212 | break; |
| 2253 | } | 2213 | } |
| 2254 | goto ret1; | 2214 | goto ret1; |
