00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 #ifndef Long
00167 #define Long long
00168 #endif
00169 #ifndef ULong
00170 typedef unsigned Long ULong;
00171 #endif
00172
00173 #ifdef DEBUG
00174 #include "stdio.h"
00175 #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
00176 #endif
00177
00178 #include "stdlib.h"
00179 #include "string.h"
00180
00181 #ifdef USE_LOCALE
00182 #include "locale.h"
00183 #endif
00184
00185 #ifdef MALLOC
00186 #ifdef KR_headers
00187 extern char *MALLOC();
00188 #else
00189 extern void *MALLOC(size_t);
00190 #endif
00191 #else
00192 #define MALLOC malloc
00193 #endif
00194
00195 #ifndef Omit_Private_Memory
00196 #ifndef PRIVATE_MEM
00197 #define PRIVATE_MEM 2304
00198 #endif
00199 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
00200 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
00201 #endif
00202
00203 #undef IEEE_Arith
00204 #undef Avoid_Underflow
00205 #ifdef IEEE_MC68k
00206 #define IEEE_Arith
00207 #endif
00208 #ifdef IEEE_8087
00209 #define IEEE_Arith
00210 #endif
00211
00212 #include "errno.h"
00213
00214 #ifdef Bad_float_h
00215
00216 #ifdef IEEE_Arith
00217 #define DBL_DIG 15
00218 #define DBL_MAX_10_EXP 308
00219 #define DBL_MAX_EXP 1024
00220 #define FLT_RADIX 2
00221 #endif
00222
00223 #ifdef IBM
00224 #define DBL_DIG 16
00225 #define DBL_MAX_10_EXP 75
00226 #define DBL_MAX_EXP 63
00227 #define FLT_RADIX 16
00228 #define DBL_MAX 7.2370055773322621e+75
00229 #endif
00230
00231 #ifdef VAX
00232 #define DBL_DIG 16
00233 #define DBL_MAX_10_EXP 38
00234 #define DBL_MAX_EXP 127
00235 #define FLT_RADIX 2
00236 #define DBL_MAX 1.7014118346046923e+38
00237 #endif
00238
00239 #ifndef LONG_MAX
00240 #define LONG_MAX 2147483647
00241 #endif
00242
00243 #else
00244 #include "float.h"
00245 #endif
00246
00247 #ifndef __MATH_H__
00248 #include "math.h"
00249 #endif
00250
00251 #ifdef __cplusplus
00252 extern "C" {
00253 #endif
00254
00255 #ifndef CONST
00256 #ifdef KR_headers
00257 #define CONST
00258 #else
00259 #define CONST const
00260 #endif
00261 #endif
00262
00263 #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
00264 Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
00265 #endif
00266
00267 typedef union { double d; ULong L[2]; } U;
00268
00269 #ifdef YES_ALIAS
00270 #define dval(x) x
00271 #ifdef IEEE_8087
00272 #define word0(x) ((ULong *)&x)[1]
00273 #define word1(x) ((ULong *)&x)[0]
00274 #else
00275 #define word0(x) ((ULong *)&x)[0]
00276 #define word1(x) ((ULong *)&x)[1]
00277 #endif
00278 #else
00279 #ifdef IEEE_8087
00280 #define word0(x) ((U*)&x)->L[1]
00281 #define word1(x) ((U*)&x)->L[0]
00282 #else
00283 #define word0(x) ((U*)&x)->L[0]
00284 #define word1(x) ((U*)&x)->L[1]
00285 #endif
00286 #define dval(x) ((U*)&x)->d
00287 #endif
00288
00289
00290
00291
00292
00293 #if defined(IEEE_8087) + defined(VAX)
00294 #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
00295 ((unsigned short *)a)[0] = (unsigned short)c, a++)
00296 #else
00297 #define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
00298 ((unsigned short *)a)[1] = (unsigned short)c, a++)
00299 #endif
00300
00301
00302
00303
00304
00305
00306
00307 #ifdef IEEE_Arith
00308 #define Exp_shift 20
00309 #define Exp_shift1 20
00310 #define Exp_msk1 0x100000
00311 #define Exp_msk11 0x100000
00312 #define Exp_mask 0x7ff00000
00313 #define P 53
00314 #define Bias 1023
00315 #define Emin (-1022)
00316 #define Exp_1 0x3ff00000
00317 #define Exp_11 0x3ff00000
00318 #define Ebits 11
00319 #define Frac_mask 0xfffff
00320 #define Frac_mask1 0xfffff
00321 #define Ten_pmax 22
00322 #define Bletch 0x10
00323 #define Bndry_mask 0xfffff
00324 #define Bndry_mask1 0xfffff
00325 #define LSB 1
00326 #define Sign_bit 0x80000000
00327 #define Log2P 1
00328 #define Tiny0 0
00329 #define Tiny1 1
00330 #define Quick_max 14
00331 #define Int_max 14
00332 #ifndef NO_IEEE_Scale
00333 #define Avoid_Underflow
00334 #ifdef Flush_Denorm
00335 #undef Sudden_Underflow
00336 #endif
00337 #endif
00338
00339 #ifndef Flt_Rounds
00340 #ifdef FLT_ROUNDS
00341 #define Flt_Rounds FLT_ROUNDS
00342 #else
00343 #define Flt_Rounds 1
00344 #endif
00345 #endif
00346
00347 #ifdef Honor_FLT_ROUNDS
00348 #define Rounding rounding
00349 #undef Check_FLT_ROUNDS
00350 #define Check_FLT_ROUNDS
00351 #else
00352 #define Rounding Flt_Rounds
00353 #endif
00354
00355 #else
00356 #undef Check_FLT_ROUNDS
00357 #undef Honor_FLT_ROUNDS
00358 #undef SET_INEXACT
00359 #undef Sudden_Underflow
00360 #define Sudden_Underflow
00361 #ifdef IBM
00362 #undef Flt_Rounds
00363 #define Flt_Rounds 0
00364 #define Exp_shift 24
00365 #define Exp_shift1 24
00366 #define Exp_msk1 0x1000000
00367 #define Exp_msk11 0x1000000
00368 #define Exp_mask 0x7f000000
00369 #define P 14
00370 #define Bias 65
00371 #define Exp_1 0x41000000
00372 #define Exp_11 0x41000000
00373 #define Ebits 8
00374 #define Frac_mask 0xffffff
00375 #define Frac_mask1 0xffffff
00376 #define Bletch 4
00377 #define Ten_pmax 22
00378 #define Bndry_mask 0xefffff
00379 #define Bndry_mask1 0xffffff
00380 #define LSB 1
00381 #define Sign_bit 0x80000000
00382 #define Log2P 4
00383 #define Tiny0 0x100000
00384 #define Tiny1 0
00385 #define Quick_max 14
00386 #define Int_max 15
00387 #else
00388 #undef Flt_Rounds
00389 #define Flt_Rounds 1
00390 #define Exp_shift 23
00391 #define Exp_shift1 7
00392 #define Exp_msk1 0x80
00393 #define Exp_msk11 0x800000
00394 #define Exp_mask 0x7f80
00395 #define P 56
00396 #define Bias 129
00397 #define Exp_1 0x40800000
00398 #define Exp_11 0x4080
00399 #define Ebits 8
00400 #define Frac_mask 0x7fffff
00401 #define Frac_mask1 0xffff007f
00402 #define Ten_pmax 24
00403 #define Bletch 2
00404 #define Bndry_mask 0xffff007f
00405 #define Bndry_mask1 0xffff007f
00406 #define LSB 0x10000
00407 #define Sign_bit 0x8000
00408 #define Log2P 1
00409 #define Tiny0 0x80
00410 #define Tiny1 0
00411 #define Quick_max 15
00412 #define Int_max 15
00413 #endif
00414 #endif
00415
00416 #ifndef IEEE_Arith
00417 #define ROUND_BIASED
00418 #endif
00419
00420 #ifdef RND_PRODQUOT
00421 #define rounded_product(a,b) a = rnd_prod(a, b)
00422 #define rounded_quotient(a,b) a = rnd_quot(a, b)
00423 #ifdef KR_headers
00424 extern double rnd_prod(), rnd_quot();
00425 #else
00426 extern double rnd_prod(double, double), rnd_quot(double, double);
00427 #endif
00428 #else
00429 #define rounded_product(a,b) a *= b
00430 #define rounded_quotient(a,b) a /= b
00431 #endif
00432
00433 #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
00434 #define Big1 0xffffffff
00435
00436 #ifndef Pack_32
00437 #define Pack_32
00438 #endif
00439
00440 #ifdef KR_headers
00441 #define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff)
00442 #else
00443 #define FFFFFFFF 0xffffffffUL
00444 #endif
00445
00446 #ifdef NO_LONG_LONG
00447 #undef ULLong
00448 #ifdef Just_16
00449 #undef Pack_32
00450
00451
00452
00453
00454
00455 #endif
00456 #else
00457 #ifndef Llong
00458 #define Llong long long
00459 #endif
00460 #ifndef ULLong
00461 #define ULLong unsigned Llong
00462 #endif
00463 #endif
00464
00465 #ifndef MULTIPLE_THREADS
00466 #define ACQUIRE_DTOA_LOCK(n)
00467 #define FREE_DTOA_LOCK(n)
00468 #endif
00469
00470 #define Kmax 15
00471
00472 #ifdef __cplusplus
00473 extern "C" double strtod(const char *s00, char **se);
00474 extern "C" char *dtoa(double d, int mode, int ndigits,
00475 int *decpt, int *sign, char **rve);
00476 #endif
00477
00478 struct
00479 Bigint {
00480 struct Bigint *next;
00481 int k, maxwds, sign, wds;
00482 ULong x[1];
00483 };
00484
00485 typedef struct Bigint Bigint;
00486
00487 static Bigint *freelist[Kmax+1];
00488
00489 static Bigint *
00490 Balloc
00491 #ifdef KR_headers
00492 (k) int k;
00493 #else
00494 (int k)
00495 #endif
00496 {
00497 int x;
00498 Bigint *rv;
00499 #ifndef Omit_Private_Memory
00500 unsigned int len;
00501 #endif
00502
00503 ACQUIRE_DTOA_LOCK(0);
00504 if ((rv = freelist[k])) {
00505 freelist[k] = rv->next;
00506 }
00507 else {
00508 x = 1 << k;
00509 #ifdef Omit_Private_Memory
00510 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
00511 #else
00512 len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
00513 /sizeof(double);
00514 if (pmem_next - private_mem + len <= PRIVATE_mem) {
00515 rv = (Bigint*)pmem_next;
00516 pmem_next += len;
00517 }
00518 else
00519 rv = (Bigint*)MALLOC(len*sizeof(double));
00520 #endif
00521 rv->k = k;
00522 rv->maxwds = x;
00523 }
00524 FREE_DTOA_LOCK(0);
00525 rv->sign = rv->wds = 0;
00526 return rv;
00527 }
00528
00529 static void
00530 Bfree
00531 #ifdef KR_headers
00532 (v) Bigint *v;
00533 #else
00534 (Bigint *v)
00535 #endif
00536 {
00537 if (v) {
00538 ACQUIRE_DTOA_LOCK(0);
00539 v->next = freelist[v->k];
00540 freelist[v->k] = v;
00541 FREE_DTOA_LOCK(0);
00542 }
00543 }
00544
00545 #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
00546 y->wds*sizeof(Long) + 2*sizeof(int))
00547
00548 static Bigint *
00549 multadd
00550 #ifdef KR_headers
00551 (b, m, a) Bigint *b; int m, a;
00552 #else
00553 (Bigint *b, int m, int a)
00554 #endif
00555 {
00556 int i, wds;
00557 #ifdef ULLong
00558 ULong *x;
00559 ULLong carry, y;
00560 #else
00561 ULong carry, *x, y;
00562 #ifdef Pack_32
00563 ULong xi, z;
00564 #endif
00565 #endif
00566 Bigint *b1;
00567
00568 wds = b->wds;
00569 x = b->x;
00570 i = 0;
00571 carry = a;
00572 do {
00573 #ifdef ULLong
00574 y = *x * (ULLong)m + carry;
00575 carry = y >> 32;
00576 *x++ = y & FFFFFFFF;
00577 #else
00578 #ifdef Pack_32
00579 xi = *x;
00580 y = (xi & 0xffff) * m + carry;
00581 z = (xi >> 16) * m + (y >> 16);
00582 carry = z >> 16;
00583 *x++ = (z << 16) + (y & 0xffff);
00584 #else
00585 y = *x * m + carry;
00586 carry = y >> 16;
00587 *x++ = y & 0xffff;
00588 #endif
00589 #endif
00590 }
00591 while(++i < wds);
00592 if (carry) {
00593 if (wds >= b->maxwds) {
00594 b1 = Balloc(b->k+1);
00595 Bcopy(b1, b);
00596 Bfree(b);
00597 b = b1;
00598 }
00599 b->x[wds++] = carry;
00600 b->wds = wds;
00601 }
00602 return b;
00603 }
00604
00605 static Bigint *
00606 s2b
00607 #ifdef KR_headers
00608 (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
00609 #else
00610 (CONST char *s, int nd0, int nd, ULong y9)
00611 #endif
00612 {
00613 Bigint *b;
00614 int i, k;
00615 Long x, y;
00616
00617 x = (nd + 8) / 9;
00618 for(k = 0, y = 1; x > y; y <<= 1, k++) ;
00619 #ifdef Pack_32
00620 b = Balloc(k);
00621 b->x[0] = y9;
00622 b->wds = 1;
00623 #else
00624 b = Balloc(k+1);
00625 b->x[0] = y9 & 0xffff;
00626 b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
00627 #endif
00628
00629 i = 9;
00630 if (9 < nd0) {
00631 s += 9;
00632 do b = multadd(b, 10, *s++ - '0');
00633 while(++i < nd0);
00634 s++;
00635 }
00636 else
00637 s += 10;
00638 for(; i < nd; i++)
00639 b = multadd(b, 10, *s++ - '0');
00640 return b;
00641 }
00642
00643 static int
00644 hi0bits
00645 #ifdef KR_headers
00646 (x) register ULong x;
00647 #else
00648 (register ULong x)
00649 #endif
00650 {
00651 register int k = 0;
00652
00653 if (!(x & 0xffff0000)) {
00654 k = 16;
00655 x <<= 16;
00656 }
00657 if (!(x & 0xff000000)) {
00658 k += 8;
00659 x <<= 8;
00660 }
00661 if (!(x & 0xf0000000)) {
00662 k += 4;
00663 x <<= 4;
00664 }
00665 if (!(x & 0xc0000000)) {
00666 k += 2;
00667 x <<= 2;
00668 }
00669 if (!(x & 0x80000000)) {
00670 k++;
00671 if (!(x & 0x40000000))
00672 return 32;
00673 }
00674 return k;
00675 }
00676
00677 static int
00678 lo0bits
00679 #ifdef KR_headers
00680 (y) ULong *y;
00681 #else
00682 (ULong *y)
00683 #endif
00684 {
00685 register int k;
00686 register ULong x = *y;
00687
00688 if (x & 7) {
00689 if (x & 1)
00690 return 0;
00691 if (x & 2) {
00692 *y = x >> 1;
00693 return 1;
00694 }
00695 *y = x >> 2;
00696 return 2;
00697 }
00698 k = 0;
00699 if (!(x & 0xffff)) {
00700 k = 16;
00701 x >>= 16;
00702 }
00703 if (!(x & 0xff)) {
00704 k += 8;
00705 x >>= 8;
00706 }
00707 if (!(x & 0xf)) {
00708 k += 4;
00709 x >>= 4;
00710 }
00711 if (!(x & 0x3)) {
00712 k += 2;
00713 x >>= 2;
00714 }
00715 if (!(x & 1)) {
00716 k++;
00717 x >>= 1;
00718 if (!x)
00719 return 32;
00720 }
00721 *y = x;
00722 return k;
00723 }
00724
00725 static Bigint *
00726 i2b
00727 #ifdef KR_headers
00728 (i) int i;
00729 #else
00730 (int i)
00731 #endif
00732 {
00733 Bigint *b;
00734
00735 b = Balloc(1);
00736 b->x[0] = i;
00737 b->wds = 1;
00738 return b;
00739 }
00740
00741 static Bigint *
00742 mult
00743 #ifdef KR_headers
00744 (a, b) Bigint *a, *b;
00745 #else
00746 (Bigint *a, Bigint *b)
00747 #endif
00748 {
00749 Bigint *c;
00750 int k, wa, wb, wc;
00751 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
00752 ULong y;
00753 #ifdef ULLong
00754 ULLong carry, z;
00755 #else
00756 ULong carry, z;
00757 #ifdef Pack_32
00758 ULong z2;
00759 #endif
00760 #endif
00761
00762 if (a->wds < b->wds) {
00763 c = a;
00764 a = b;
00765 b = c;
00766 }
00767 k = a->k;
00768 wa = a->wds;
00769 wb = b->wds;
00770 wc = wa + wb;
00771 if (wc > a->maxwds)
00772 k++;
00773 c = Balloc(k);
00774 for(x = c->x, xa = x + wc; x < xa; x++)
00775 *x = 0;
00776 xa = a->x;
00777 xae = xa + wa;
00778 xb = b->x;
00779 xbe = xb + wb;
00780 xc0 = c->x;
00781 #ifdef ULLong
00782 for(; xb < xbe; xc0++) {
00783 if ((y = *xb++)) {
00784 x = xa;
00785 xc = xc0;
00786 carry = 0;
00787 do {
00788 z = *x++ * (ULLong)y + *xc + carry;
00789 carry = z >> 32;
00790 *xc++ = z & FFFFFFFF;
00791 }
00792 while(x < xae);
00793 *xc = carry;
00794 }
00795 }
00796 #else
00797 #ifdef Pack_32
00798 for(; xb < xbe; xb++, xc0++) {
00799 if (y = *xb & 0xffff) {
00800 x = xa;
00801 xc = xc0;
00802 carry = 0;
00803 do {
00804 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
00805 carry = z >> 16;
00806 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
00807 carry = z2 >> 16;
00808 Storeinc(xc, z2, z);
00809 }
00810 while(x < xae);
00811 *xc = carry;
00812 }
00813 if (y = *xb >> 16) {
00814 x = xa;
00815 xc = xc0;
00816 carry = 0;
00817 z2 = *xc;
00818 do {
00819 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
00820 carry = z >> 16;
00821 Storeinc(xc, z, z2);
00822 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
00823 carry = z2 >> 16;
00824 }
00825 while(x < xae);
00826 *xc = z2;
00827 }
00828 }
00829 #else
00830 for(; xb < xbe; xc0++) {
00831 if (y = *xb++) {
00832 x = xa;
00833 xc = xc0;
00834 carry = 0;
00835 do {
00836 z = *x++ * y + *xc + carry;
00837 carry = z >> 16;
00838 *xc++ = z & 0xffff;
00839 }
00840 while(x < xae);
00841 *xc = carry;
00842 }
00843 }
00844 #endif
00845 #endif
00846 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
00847 c->wds = wc;
00848 return c;
00849 }
00850
00851 static Bigint *p5s;
00852
00853 static Bigint *
00854 pow5mult
00855 #ifdef KR_headers
00856 (b, k) Bigint *b; int k;
00857 #else
00858 (Bigint *b, int k)
00859 #endif
00860 {
00861 Bigint *b1, *p5, *p51;
00862 int i;
00863 static int p05[3] = { 5, 25, 125 };
00864
00865 if ((i = k & 3))
00866 b = multadd(b, p05[i-1], 0);
00867
00868 if (!(k >>= 2))
00869 return b;
00870 if (!(p5 = p5s)) {
00871
00872 #ifdef MULTIPLE_THREADS
00873 ACQUIRE_DTOA_LOCK(1);
00874 if (!(p5 = p5s)) {
00875 p5 = p5s = i2b(625);
00876 p5->next = 0;
00877 }
00878 FREE_DTOA_LOCK(1);
00879 #else
00880 p5 = p5s = i2b(625);
00881 p5->next = 0;
00882 #endif
00883 }
00884 for(;;) {
00885 if (k & 1) {
00886 b1 = mult(b, p5);
00887 Bfree(b);
00888 b = b1;
00889 }
00890 if (!(k >>= 1))
00891 break;
00892 if (!(p51 = p5->next)) {
00893 #ifdef MULTIPLE_THREADS
00894 ACQUIRE_DTOA_LOCK(1);
00895 if (!(p51 = p5->next)) {
00896 p51 = p5->next = mult(p5,p5);
00897 p51->next = 0;
00898 }
00899 FREE_DTOA_LOCK(1);
00900 #else
00901 p51 = p5->next = mult(p5,p5);
00902 p51->next = 0;
00903 #endif
00904 }
00905 p5 = p51;
00906 }
00907 return b;
00908 }
00909
00910 static Bigint *
00911 lshift
00912 #ifdef KR_headers
00913 (b, k) Bigint *b; int k;
00914 #else
00915 (Bigint *b, int k)
00916 #endif
00917 {
00918 int i, k1, n, n1;
00919 Bigint *b1;
00920 ULong *x, *x1, *xe, z;
00921
00922 #ifdef Pack_32
00923 n = k >> 5;
00924 #else
00925 n = k >> 4;
00926 #endif
00927 k1 = b->k;
00928 n1 = n + b->wds + 1;
00929 for(i = b->maxwds; n1 > i; i <<= 1)
00930 k1++;
00931 b1 = Balloc(k1);
00932 x1 = b1->x;
00933 for(i = 0; i < n; i++)
00934 *x1++ = 0;
00935 x = b->x;
00936 xe = x + b->wds;
00937 #ifdef Pack_32
00938 if (k &= 0x1f) {
00939 k1 = 32 - k;
00940 z = 0;
00941 do {
00942 *x1++ = *x << k | z;
00943 z = *x++ >> k1;
00944 }
00945 while(x < xe);
00946 if ((*x1 = z))
00947 ++n1;
00948 }
00949 #else
00950 if (k &= 0xf) {
00951 k1 = 16 - k;
00952 z = 0;
00953 do {
00954 *x1++ = *x << k & 0xffff | z;
00955 z = *x++ >> k1;
00956 }
00957 while(x < xe);
00958 if (*x1 = z)
00959 ++n1;
00960 }
00961 #endif
00962 else do
00963 *x1++ = *x++;
00964 while(x < xe);
00965 b1->wds = n1 - 1;
00966 Bfree(b);
00967 return b1;
00968 }
00969
00970 static int
00971 cmp
00972 #ifdef KR_headers
00973 (a, b) Bigint *a, *b;
00974 #else
00975 (Bigint *a, Bigint *b)
00976 #endif
00977 {
00978 ULong *xa, *xa0, *xb, *xb0;
00979 int i, j;
00980
00981 i = a->wds;
00982 j = b->wds;
00983 #ifdef DEBUG
00984 if (i > 1 && !a->x[i-1])
00985 Bug("cmp called with a->x[a->wds-1] == 0");
00986 if (j > 1 && !b->x[j-1])
00987 Bug("cmp called with b->x[b->wds-1] == 0");
00988 #endif
00989 if (i -= j)
00990 return i;
00991 xa0 = a->x;
00992 xa = xa0 + j;
00993 xb0 = b->x;
00994 xb = xb0 + j;
00995 for(;;) {
00996 if (*--xa != *--xb)
00997 return *xa < *xb ? -1 : 1;
00998 if (xa <= xa0)
00999 break;
01000 }
01001 return 0;
01002 }
01003
01004 static Bigint *
01005 diff
01006 #ifdef KR_headers
01007 (a, b) Bigint *a, *b;
01008 #else
01009 (Bigint *a, Bigint *b)
01010 #endif
01011 {
01012 Bigint *c;
01013 int i, wa, wb;
01014 ULong *xa, *xae, *xb, *xbe, *xc;
01015 #ifdef ULLong
01016 ULLong borrow, y;
01017 #else
01018 ULong borrow, y;
01019 #ifdef Pack_32
01020 ULong z;
01021 #endif
01022 #endif
01023
01024 i = cmp(a,b);
01025 if (!i) {
01026 c = Balloc(0);
01027 c->wds = 1;
01028 c->x[0] = 0;
01029 return c;
01030 }
01031 if (i < 0) {
01032 c = a;
01033 a = b;
01034 b = c;
01035 i = 1;
01036 }
01037 else
01038 i = 0;
01039 c = Balloc(a->k);
01040 c->sign = i;
01041 wa = a->wds;
01042 xa = a->x;
01043 xae = xa + wa;
01044 wb = b->wds;
01045 xb = b->x;
01046 xbe = xb + wb;
01047 xc = c->x;
01048 borrow = 0;
01049 #ifdef ULLong
01050 do {
01051 y = (ULLong)*xa++ - *xb++ - borrow;
01052 borrow = y >> 32 & (ULong)1;
01053 *xc++ = y & FFFFFFFF;
01054 }
01055 while(xb < xbe);
01056 while(xa < xae) {
01057 y = *xa++ - borrow;
01058 borrow = y >> 32 & (ULong)1;
01059 *xc++ = y & FFFFFFFF;
01060 }
01061 #else
01062 #ifdef Pack_32
01063 do {
01064 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
01065 borrow = (y & 0x10000) >> 16;
01066 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
01067 borrow = (z & 0x10000) >> 16;
01068 Storeinc(xc, z, y);
01069 }
01070 while(xb < xbe);
01071 while(xa < xae) {
01072 y = (*xa & 0xffff) - borrow;
01073 borrow = (y & 0x10000) >> 16;
01074 z = (*xa++ >> 16) - borrow;
01075 borrow = (z & 0x10000) >> 16;
01076 Storeinc(xc, z, y);
01077 }
01078 #else
01079 do {
01080 y = *xa++ - *xb++ - borrow;
01081 borrow = (y & 0x10000) >> 16;
01082 *xc++ = y & 0xffff;
01083 }
01084 while(xb < xbe);
01085 while(xa < xae) {
01086 y = *xa++ - borrow;
01087 borrow = (y & 0x10000) >> 16;
01088 *xc++ = y & 0xffff;
01089 }
01090 #endif
01091 #endif
01092 while(!*--xc)
01093 wa--;
01094 c->wds = wa;
01095 return c;
01096 }
01097
01098 static double
01099 ulp
01100 #ifdef KR_headers
01101 (x) double x;
01102 #else
01103 (double x)
01104 #endif
01105 {
01106 register Long L;
01107 double a;
01108
01109 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
01110 #ifndef Avoid_Underflow
01111 #ifndef Sudden_Underflow
01112 if (L > 0) {
01113 #endif
01114 #endif
01115 #ifdef IBM
01116 L |= Exp_msk1 >> 4;
01117 #endif
01118 word0(a) = L;
01119 word1(a) = 0;
01120 #ifndef Avoid_Underflow
01121 #ifndef Sudden_Underflow
01122 }
01123 else {
01124 L = -L >> Exp_shift;
01125 if (L < Exp_shift) {
01126 word0(a) = 0x80000 >> L;
01127 word1(a) = 0;
01128 }
01129 else {
01130 word0(a) = 0;
01131 L -= Exp_shift;
01132 word1(a) = L >= 31 ? 1 : 1 << 31 - L;
01133 }
01134 }
01135 #endif
01136 #endif
01137 return dval(a);
01138 }
01139
01140 static double
01141 b2d
01142 #ifdef KR_headers
01143 (a, e) Bigint *a; int *e;
01144 #else
01145 (Bigint *a, int *e)
01146 #endif
01147 {
01148 ULong *xa, *xa0, w, y, z;
01149 int k;
01150 double d;
01151 #ifdef VAX
01152 ULong d0, d1;
01153 #else
01154 #define d0 word0(d)
01155 #define d1 word1(d)
01156 #endif
01157
01158 xa0 = a->x;
01159 xa = xa0 + a->wds;
01160 y = *--xa;
01161 #ifdef DEBUG
01162 if (!y) Bug("zero y in b2d");
01163 #endif
01164 k = hi0bits(y);
01165 *e = 32 - k;
01166 #ifdef Pack_32
01167 if (k < Ebits) {
01168 d0 = Exp_1 | (y >> (Ebits - k));
01169 w = xa > xa0 ? *--xa : 0;
01170 d1 = (y << ((32-Ebits) + k)) | (w >> (Ebits - k));
01171 goto ret_d;
01172 }
01173 z = xa > xa0 ? *--xa : 0;
01174 if (k -= Ebits) {
01175 d0 = Exp_1 | (y << k) | (z >> (32 - k));
01176 y = xa > xa0 ? *--xa : 0;
01177 d1 = (z << k) | (y >> (32 - k));
01178 }
01179 else {
01180 d0 = Exp_1 | y;
01181 d1 = z;
01182 }
01183 #else
01184 if (k < Ebits + 16) {
01185 z = xa > xa0 ? *--xa : 0;
01186 d0 = Exp_1 | (y << (k - Ebits)) | (z >> (Ebits + 16 - k));
01187 w = xa > xa0 ? *--xa : 0;
01188 y = xa > xa0 ? *--xa : 0;
01189 d1 = (z << (k + 16 - Ebits)) | (w << (k - Ebits)) | (y >> (16 + Ebits - k));
01190 goto ret_d;
01191 }
01192 z = xa > xa0 ? *--xa : 0;
01193 w = xa > xa0 ? *--xa : 0;
01194 k -= Ebits + 16;
01195 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
01196 y = xa > xa0 ? *--xa : 0;
01197 d1 = w << k + 16 | y << k;
01198 #endif
01199 ret_d:
01200 #ifdef VAX
01201 word0(d) = d0 >> 16 | d0 << 16;
01202 word1(d) = d1 >> 16 | d1 << 16;
01203 #else
01204 #undef d0
01205 #undef d1
01206 #endif
01207 return dval(d);
01208 }
01209
01210 static Bigint *
01211 d2b
01212 #ifdef KR_headers
01213 (d, e, bits) double d; int *e, *bits;
01214 #else
01215 (double d, int *e, int *bits)
01216 #endif
01217 {
01218 Bigint *b;
01219 int de, k;
01220 ULong *x, y, z;
01221 #ifndef Sudden_Underflow
01222 int i;
01223 #endif
01224 #ifdef VAX
01225 ULong d0, d1;
01226 d0 = word0(d) >> 16 | word0(d) << 16;
01227 d1 = word1(d) >> 16 | word1(d) << 16;
01228 #else
01229 #define d0 word0(d)
01230 #define d1 word1(d)
01231 #endif
01232
01233 #ifdef Pack_32
01234 b = Balloc(1);
01235 #else
01236 b = Balloc(2);
01237 #endif
01238 x = b->x;
01239
01240 z = d0 & Frac_mask;
01241 d0 &= 0x7fffffff;
01242 #ifdef Sudden_Underflow
01243 de = (int)(d0 >> Exp_shift);
01244 #ifndef IBM
01245 z |= Exp_msk11;
01246 #endif
01247 #else
01248 if ((de = (int)(d0 >> Exp_shift)))
01249 z |= Exp_msk1;
01250 #endif
01251 #ifdef Pack_32
01252 if ((y = d1)) {
01253 if ((k = lo0bits(&y))) {
01254 x[0] = y | (z << (32 - k));
01255 z >>= k;
01256 }
01257 else
01258 x[0] = y;
01259 #ifndef Sudden_Underflow
01260 i =
01261 #endif
01262 b->wds = (x[1] = z) ? 2 : 1;
01263 }
01264 else {
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274 k = lo0bits(&z);
01275 x[0] = z;
01276 #ifndef Sudden_Underflow
01277 i =
01278 #endif
01279 b->wds = 1;
01280 k += 32;
01281 }
01282 #else
01283 if (y = d1) {
01284 if (k = lo0bits(&y))
01285 if (k >= 16) {
01286 x[0] = y | z << 32 - k & 0xffff;
01287 x[1] = z >> k - 16 & 0xffff;
01288 x[2] = z >> k;
01289 i = 2;
01290 }
01291 else {
01292 x[0] = y & 0xffff;
01293 x[1] = y >> 16 | z << 16 - k & 0xffff;
01294 x[2] = z >> k & 0xffff;
01295 x[3] = z >> k+16;
01296 i = 3;
01297 }
01298 else {
01299 x[0] = y & 0xffff;
01300 x[1] = y >> 16;
01301 x[2] = z & 0xffff;
01302 x[3] = z >> 16;
01303 i = 3;
01304 }
01305 }
01306 else {
01307 #ifdef DEBUG
01308 if (!z)
01309 Bug("Zero passed to d2b");
01310 #endif
01311 k = lo0bits(&z);
01312 if (k >= 16) {
01313 x[0] = z;
01314 i = 0;
01315 }
01316 else {
01317 x[0] = z & 0xffff;
01318 x[1] = z >> 16;
01319 i = 1;
01320 }
01321 k += 32;
01322 }
01323 while(!x[i])
01324 --i;
01325 b->wds = i + 1;
01326 #endif
01327 #ifndef Sudden_Underflow
01328 if (de) {
01329 #endif
01330 #ifdef IBM
01331 *e = (de - Bias - (P-1) << 2) + k;
01332 *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
01333 #else
01334 *e = de - Bias - (P-1) + k;
01335 *bits = P - k;
01336 #endif
01337 #ifndef Sudden_Underflow
01338 }
01339 else {
01340 *e = de - Bias - (P-1) + 1 + k;
01341 #ifdef Pack_32
01342 *bits = 32*i - hi0bits(x[i-1]);
01343 #else
01344 *bits = (i+2)*16 - hi0bits(x[i]);
01345 #endif
01346 }
01347 #endif
01348 return b;
01349 }
01350 #undef d0
01351 #undef d1
01352
01353 static double
01354 ratio
01355 #ifdef KR_headers
01356 (a, b) Bigint *a, *b;
01357 #else
01358 (Bigint *a, Bigint *b)
01359 #endif
01360 {
01361 double da, db;
01362 int k, ka, kb;
01363
01364 dval(da) = b2d(a, &ka);
01365 dval(db) = b2d(b, &kb);
01366 #ifdef Pack_32
01367 k = ka - kb + 32*(a->wds - b->wds);
01368 #else
01369 k = ka - kb + 16*(a->wds - b->wds);
01370 #endif
01371 #ifdef IBM
01372 if (k > 0) {
01373 word0(da) += (k >> 2)*Exp_msk1;
01374 if (k &= 3)
01375 dval(da) *= 1 << k;
01376 }
01377 else {
01378 k = -k;
01379 word0(db) += (k >> 2)*Exp_msk1;
01380 if (k &= 3)
01381 dval(db) *= 1 << k;
01382 }
01383 #else
01384 if (k > 0)
01385 word0(da) += k*Exp_msk1;
01386 else {
01387 k = -k;
01388 word0(db) += k*Exp_msk1;
01389 }
01390 #endif
01391 return dval(da) / dval(db);
01392 }
01393
01394 static CONST double
01395 tens[] = {
01396 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
01397 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
01398 1e20, 1e21, 1e22
01399 #ifdef VAX
01400 , 1e23, 1e24
01401 #endif
01402 };
01403
01404 static CONST double
01405 #ifdef IEEE_Arith
01406 bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
01407 static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
01408 #ifdef Avoid_Underflow
01409 9007199254740992.*9007199254740992.e-256
01410
01411 #else
01412 1e-256
01413 #endif
01414 };
01415
01416
01417 #define Scale_Bit 0x10
01418 #define n_bigtens 5
01419 #else
01420 #ifdef IBM
01421 bigtens[] = { 1e16, 1e32, 1e64 };
01422 static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
01423 #define n_bigtens 3
01424 #else
01425 bigtens[] = { 1e16, 1e32 };
01426 static CONST double tinytens[] = { 1e-16, 1e-32 };
01427 #define n_bigtens 2
01428 #endif
01429 #endif
01430
01431 #ifndef IEEE_Arith
01432 #undef INFNAN_CHECK
01433 #endif
01434
01435 #ifdef INFNAN_CHECK
01436
01437 #ifndef NAN_WORD0
01438 #define NAN_WORD0 0x7ff80000
01439 #endif
01440
01441 #ifndef NAN_WORD1
01442 #define NAN_WORD1 0
01443 #endif
01444
01445 static int
01446 match
01447 #ifdef KR_headers
01448 (sp, t) char **sp, *t;
01449 #else
01450 (CONST char **sp, char *t)
01451 #endif
01452 {
01453 int c, d;
01454 CONST char *s = *sp;
01455
01456 while(d = *t++) {
01457 if ((c = *++s) >= 'A' && c <= 'Z')
01458 c += 'a' - 'A';
01459 if (c != d)
01460 return 0;
01461 }
01462 *sp = s + 1;
01463 return 1;
01464 }
01465
01466 #ifndef No_Hex_NaN
01467 static void
01468 hexnan
01469 #ifdef KR_headers
01470 (rvp, sp) double *rvp; CONST char **sp;
01471 #else
01472 (double *rvp, CONST char **sp)
01473 #endif
01474 {
01475 ULong c, x[2];
01476 CONST char *s;
01477 int havedig, udx0, xshift;
01478
01479 x[0] = x[1] = 0;
01480 havedig = xshift = 0;
01481 udx0 = 1;
01482 s = *sp;
01483 while(c = *(CONST unsigned char*)++s) {
01484 if (c >= '0' && c <= '9')
01485 c -= '0';
01486 else if (c >= 'a' && c <= 'f')
01487 c += 10 - 'a';
01488 else if (c >= 'A' && c <= 'F')
01489 c += 10 - 'A';
01490 else if (c <= ' ') {
01491 if (udx0 && havedig) {
01492 udx0 = 0;
01493 xshift = 1;
01494 }
01495 continue;
01496 }
01497 else if ( c == ')' && havedig) {
01498 *sp = s + 1;
01499 break;
01500 }
01501 else
01502 return;
01503 havedig = 1;
01504 if (xshift) {
01505 xshift = 0;
01506 x[0] = x[1];
01507 x[1] = 0;
01508 }
01509 if (udx0)
01510 x[0] = (x[0] << 4) | (x[1] >> 28);
01511 x[1] = (x[1] << 4) | c;
01512 }
01513 if ((x[0] &= 0xfffff) || x[1]) {
01514 word0(*rvp) = Exp_mask | x[0];
01515 word1(*rvp) = x[1];
01516 }
01517 }
01518 #endif
01519 #endif
01520
01521 double
01522 strtod
01523 #ifdef KR_headers
01524 (s00, se) CONST char *s00; char **se;
01525 #else
01526 (CONST char *s00, char **se)
01527 #endif
01528 {
01529 #ifdef Avoid_Underflow
01530 int scale;
01531 #endif
01532 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
01533 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
01534 CONST char *s, *s0, *s1;
01535 double aadj, aadj1, adj, rv, rv0;
01536 Long L;
01537 ULong y, z;
01538 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
01539 #ifdef SET_INEXACT
01540 int inexact, oldinexact;
01541 #endif
01542 #ifdef Honor_FLT_ROUNDS
01543 int rounding;
01544 #endif
01545 #ifdef USE_LOCALE
01546 CONST char *s2;
01547 #endif
01548
01549 sign = nz0 = nz = 0;
01550 dval(rv) = 0.;
01551 for(s = s00;;s++) switch(*s) {
01552 case '-':
01553 sign = 1;
01554
01555 case '+':
01556 if (*++s)
01557 goto break2;
01558
01559 case 0:
01560 goto ret0;
01561 case '\t':
01562 case '\n':
01563 case '\v':
01564 case '\f':
01565 case '\r':
01566 case ' ':
01567 continue;
01568 default:
01569 goto break2;
01570 }
01571 break2:
01572 if (*s == '0') {
01573 nz0 = 1;
01574 while(*++s == '0') ;
01575 if (!*s)
01576 goto ret;
01577 }
01578 s0 = s;
01579 y = z = 0;
01580 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
01581 if (nd < 9)
01582 y = 10*y + c - '0';
01583 else if (nd < 16)
01584 z = 10*z + c - '0';
01585 nd0 = nd;
01586 #ifdef USE_LOCALE
01587 s1 = localeconv()->decimal_point;
01588 if (c == *s1) {
01589 c = '.';
01590 if (*++s1) {
01591 s2 = s;
01592 for(;;) {
01593 if (*++s2 != *s1) {
01594 c = 0;
01595 break;
01596 }
01597 if (!*++s1) {
01598 s = s2;
01599 break;
01600 }
01601 }
01602 }
01603 }
01604 #endif
01605 if (c == '.') {
01606 c = *++s;
01607 if (!nd) {
01608 for(; c == '0'; c = *++s)
01609 nz++;
01610 if (c > '0' && c <= '9') {
01611 s0 = s;
01612 nf += nz;
01613 nz = 0;
01614 goto have_dig;
01615 }
01616 goto dig_done;
01617 }
01618 for(; c >= '0' && c <= '9'; c = *++s) {
01619 have_dig:
01620 nz++;
01621 if (c -= '0') {
01622 nf += nz;
01623 for(i = 1; i < nz; i++)
01624 if (nd++ < 9)
01625 y *= 10;
01626 else if (nd <= DBL_DIG + 1)
01627 z *= 10;
01628 if (nd++ < 9)
01629 y = 10*y + c;
01630 else if (nd <= DBL_DIG + 1)
01631 z = 10*z + c;
01632 nz = 0;
01633 }
01634 }
01635 }
01636 dig_done:
01637 e = 0;
01638 if (c == 'e' || c == 'E') {
01639 if (!nd && !nz && !nz0) {
01640 goto ret0;
01641 }
01642 s00 = s;
01643 esign = 0;
01644 switch(c = *++s) {
01645 case '-':
01646 esign = 1;
01647 case '+':
01648 c = *++s;
01649 }
01650 if (c >= '0' && c <= '9') {
01651 while(c == '0')
01652 c = *++s;
01653 if (c > '0' && c <= '9') {
01654 L = c - '0';
01655 s1 = s;
01656 while((c = *++s) >= '0' && c <= '9')
01657 L = 10*L + c - '0';
01658 if (s - s1 > 8 || L > 19999)
01659
01660
01661
01662 e = 19999;
01663 else
01664 e = (int)L;
01665 if (esign)
01666 e = -e;
01667 }
01668 else
01669 e = 0;
01670 }
01671 else
01672 s = s00;
01673 }
01674 if (!nd) {
01675 if (!nz && !nz0) {
01676 #ifdef INFNAN_CHECK
01677
01678 switch(c) {
01679 case 'i':
01680 case 'I':
01681 if (match(&s,"nf")) {
01682 --s;
01683 if (!match(&s,"inity"))
01684 ++s;
01685 word0(rv) = 0x7ff00000;
01686 word1(rv) = 0;
01687 goto ret;
01688 }
01689 break;
01690 case 'n':
01691 case 'N':
01692 if (match(&s, "an")) {
01693 word0(rv) = NAN_WORD0;
01694 word1(rv) = NAN_WORD1;
01695 #ifndef No_Hex_NaN
01696 if (*s == '(')
01697 hexnan(&rv, &s);
01698 #endif
01699 goto ret;
01700 }
01701 }
01702 #endif
01703 ret0:
01704 s = s00;
01705 sign = 0;
01706 }
01707 goto ret;
01708 }
01709 e1 = e -= nf;
01710
01711
01712
01713
01714
01715
01716 if (!nd0)
01717 nd0 = nd;
01718 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
01719 dval(rv) = y;
01720 if (k > 9) {
01721 #ifdef SET_INEXACT
01722 if (k > DBL_DIG)
01723 oldinexact = get_inexact();
01724 #endif
01725 dval(rv) = tens[k - 9] * dval(rv) + z;
01726 }
01727 bd0 = 0;
01728 if (nd <= DBL_DIG
01729 #ifndef RND_PRODQUOT
01730 #ifndef Honor_FLT_ROUNDS
01731 && Flt_Rounds == 1
01732 #endif
01733 #endif
01734 ) {
01735 if (!e)
01736 goto ret;
01737 if (e > 0) {
01738 if (e <= Ten_pmax) {
01739 #ifdef VAX
01740 goto vax_ovfl_check;
01741 #else
01742 #ifdef Honor_FLT_ROUNDS
01743
01744 if (sign) {
01745 rv = -rv;
01746 sign = 0;
01747 }
01748 #endif
01749 rounded_product(dval(rv), tens[e]);
01750 goto ret;
01751 #endif
01752 }
01753 i = DBL_DIG - nd;
01754 if (e <= Ten_pmax + i) {
01755
01756
01757
01758 #ifdef Honor_FLT_ROUNDS
01759
01760 if (sign) {
01761 rv = -rv;
01762 sign = 0;
01763 }
01764 #endif
01765 e -= i;
01766 dval(rv) *= tens[i];
01767 #ifdef VAX
01768
01769
01770
01771 vax_ovfl_check:
01772 word0(rv) -= P*Exp_msk1;
01773 rounded_product(dval(rv), tens[e]);
01774 if ((word0(rv) & Exp_mask)
01775 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
01776 goto ovfl;
01777 word0(rv) += P*Exp_msk1;
01778 #else
01779 rounded_product(dval(rv), tens[e]);
01780 #endif
01781 goto ret;
01782 }
01783 }
01784 #ifndef Inaccurate_Divide
01785 else if (e >= -Ten_pmax) {
01786 #ifdef Honor_FLT_ROUNDS
01787
01788 if (sign) {
01789 rv = -rv;
01790 sign = 0;
01791 }
01792 #endif
01793 rounded_quotient(dval(rv), tens[-e]);
01794 goto ret;
01795 }
01796 #endif
01797 }
01798 e1 += nd - k;
01799
01800 #ifdef IEEE_Arith
01801 #ifdef SET_INEXACT
01802 inexact = 1;
01803 if (k <= DBL_DIG)
01804 oldinexact = get_inexact();
01805 #endif
01806 #ifdef Avoid_Underflow
01807 scale = 0;
01808 #endif
01809 #ifdef Honor_FLT_ROUNDS
01810 if ((rounding = Flt_Rounds) >= 2) {
01811 if (sign)
01812 rounding = rounding == 2 ? 0 : 2;
01813 else
01814 if (rounding != 2)
01815 rounding = 0;
01816 }
01817 #endif
01818 #endif
01819
01820
01821
01822 if (e1 > 0) {
01823 if ((i = e1 & 15))
01824 dval(rv) *= tens[i];
01825 if (e1 &= ~15) {
01826 if (e1 > DBL_MAX_10_EXP) {
01827 ovfl:
01828 #ifndef NO_ERRNO
01829 errno = ERANGE;
01830 #endif
01831
01832 #ifdef IEEE_Arith
01833 #ifdef Honor_FLT_ROUNDS
01834 switch(rounding) {
01835 case 0:
01836 case 3:
01837 word0(rv) = Big0;
01838 word1(rv) = Big1;
01839 break;
01840 default:
01841 word0(rv) = Exp_mask;
01842 word1(rv) = 0;
01843 }
01844 #else
01845 word0(rv) = Exp_mask;
01846 word1(rv) = 0;
01847 #endif
01848 #ifdef SET_INEXACT
01849
01850 dval(rv0) = 1e300;
01851 dval(rv0) *= dval(rv0);
01852 #endif
01853 #else
01854 word0(rv) = Big0;
01855 word1(rv) = Big1;
01856 #endif
01857 if (bd0)
01858 goto retfree;
01859 goto ret;
01860 }
01861 e1 >>= 4;
01862 for(j = 0; e1 > 1; j++, e1 >>= 1)
01863 if (e1 & 1)
01864 dval(rv) *= bigtens[j];
01865
01866 word0(rv) -= P*Exp_msk1;
01867 dval(rv) *= bigtens[j];
01868 if ((z = word0(rv) & Exp_mask)
01869 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
01870 goto ovfl;
01871 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
01872
01873
01874 word0(rv) = Big0;
01875 word1(rv) = Big1;
01876 }
01877 else
01878 word0(rv) += P*Exp_msk1;
01879 }
01880 }
01881 else if (e1 < 0) {
01882 e1 = -e1;
01883 if ((i = e1 & 15))
01884 dval(rv) /= tens[i];
01885 if (e1 >>= 4) {
01886 if (e1 >= 1 << n_bigtens)
01887 goto undfl;
01888 #ifdef Avoid_Underflow
01889 if (e1 & Scale_Bit)
01890 scale = 2*P;
01891 for(j = 0; e1 > 0; j++, e1 >>= 1)
01892 if (e1 & 1)
01893 dval(rv) *= tinytens[j];
01894 if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
01895 >> Exp_shift)) > 0) {
01896
01897 if (j >= 32) {
01898 word1(rv) = 0;
01899 if (j >= 53)
01900 word0(rv) = (P+2)*Exp_msk1;
01901 else
01902 word0(rv) &= 0xffffffff << (j-32);
01903 }
01904 else
01905 word1(rv) &= 0xffffffff << j;
01906 }
01907 #else
01908 for(j = 0; e1 > 1; j++, e1 >>= 1)
01909 if (e1 & 1)
01910 dval(rv) *= tinytens[j];
01911
01912 dval(rv0) = dval(rv);
01913 dval(rv) *= tinytens[j];
01914 if (!dval(rv)) {
01915 dval(rv) = 2.*dval(rv0);
01916 dval(rv) *= tinytens[j];
01917 #endif
01918 if (!dval(rv)) {
01919 undfl:
01920 dval(rv) = 0.;
01921 #ifndef NO_ERRNO
01922 errno = ERANGE;
01923 #endif
01924 if (bd0)
01925 goto retfree;
01926 goto ret;
01927 }
01928 #ifndef Avoid_Underflow
01929 word0(rv) = Tiny0;
01930 word1(rv) = Tiny1;
01931
01932
01933
01934 }
01935 #endif
01936 }
01937 }
01938
01939
01940
01941
01942
01943 bd0 = s2b(s0, nd0, nd, y);
01944
01945 for(;;) {
01946 bd = Balloc(bd0->k);
01947 Bcopy(bd, bd0);
01948 bb = d2b(dval(rv), &bbe, &bbbits);
01949 bs = i2b(1);
01950
01951 if (e >= 0) {
01952 bb2 = bb5 = 0;
01953 bd2 = bd5 = e;
01954 }
01955 else {
01956 bb2 = bb5 = -e;
01957 bd2 = bd5 = 0;
01958 }
01959 if (bbe >= 0)
01960 bb2 += bbe;
01961 else
01962 bd2 -= bbe;
01963 bs2 = bb2;
01964 #ifdef Honor_FLT_ROUNDS
01965 if (rounding != 1)
01966 bs2++;
01967 #endif
01968 #ifdef Avoid_Underflow
01969 j = bbe - scale;
01970 i = j + bbbits - 1;
01971 if (i < Emin)
01972 j += P - Emin;
01973 else
01974 j = P + 1 - bbbits;
01975 #else
01976 #ifdef Sudden_Underflow
01977 #ifdef IBM
01978 j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
01979 #else
01980 j = P + 1 - bbbits;
01981 #endif
01982 #else
01983 j = bbe;
01984 i = j + bbbits - 1;
01985 if (i < Emin)
01986 j += P - Emin;
01987 else
01988 j = P + 1 - bbbits;
01989 #endif
01990 #endif
01991 bb2 += j;
01992 bd2 += j;
01993 #ifdef Avoid_Underflow
01994 bd2 += scale;
01995 #endif
01996 i = bb2 < bd2 ? bb2 : bd2;
01997 if (i > bs2)
01998 i = bs2;
01999 if (i > 0) {
02000 bb2 -= i;
02001 bd2 -= i;
02002 bs2 -= i;
02003 }
02004 if (bb5 > 0) {
02005 bs = pow5mult(bs, bb5);
02006 bb1 = mult(bs, bb);
02007 Bfree(bb);
02008 bb = bb1;
02009 }
02010 if (bb2 > 0)
02011 bb = lshift(bb, bb2);
02012 if (bd5 > 0)
02013 bd = pow5mult(bd, bd5);
02014 if (bd2 > 0)
02015 bd = lshift(bd, bd2);
02016 if (bs2 > 0)
02017 bs = lshift(bs, bs2);
02018 delta = diff(bb, bd);
02019 dsign = delta->sign;
02020 delta->sign = 0;
02021 i = cmp(delta, bs);
02022 #ifdef Honor_FLT_ROUNDS
02023 if (rounding != 1) {
02024 if (i < 0) {
02025
02026 if (!delta->x[0] && delta->wds <= 1) {
02027
02028 #ifdef SET_INEXACT
02029 inexact = 0;
02030 #endif
02031 break;
02032 }
02033 if (rounding) {
02034 if (dsign) {
02035 adj = 1.;
02036 goto apply_adj;
02037 }
02038 }
02039 else if (!dsign) {
02040 adj = -1.;
02041 if (!word1(rv)
02042 && !(word0(rv) & Frac_mask)) {
02043 y = word0(rv) & Exp_mask;
02044 #ifdef Avoid_Underflow
02045 if (!scale || y > 2*P*Exp_msk1)
02046 #else
02047 if (y)
02048 #endif
02049 {
02050 delta = lshift(delta,Log2P);
02051 if (cmp(delta, bs) <= 0)
02052 adj = -0.5;
02053 }
02054 }
02055 apply_adj:
02056 #ifdef Avoid_Underflow
02057 if (scale && (y = word0(rv) & Exp_mask)
02058 <= 2*P*Exp_msk1)
02059 word0(adj) += (2*P+1)*Exp_msk1 - y;
02060 #else
02061 #ifdef Sudden_Underflow
02062 if ((word0(rv) & Exp_mask) <=
02063 P*Exp_msk1) {
02064 word0(rv) += P*Exp_msk1;
02065 dval(rv) += adj*ulp(dval(rv));
02066 word0(rv) -= P*Exp_msk1;
02067 }
02068 else
02069 #endif
02070 #endif
02071 dval(rv) += adj*ulp(dval(rv));
02072 }
02073 break;
02074 }
02075 adj = ratio(delta, bs);
02076 if (adj < 1.)
02077 adj = 1.;
02078 if (adj <= 0x7ffffffe) {
02079
02080 y = adj;
02081 if (y != adj) {
02082 if (!((rounding>>1) ^ dsign))
02083 y++;
02084 adj = y;
02085 }
02086 }
02087 #ifdef Avoid_Underflow
02088 if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
02089 word0(adj) += (2*P+1)*Exp_msk1 - y;
02090 #else
02091 #ifdef Sudden_Underflow
02092 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
02093 word0(rv) += P*Exp_msk1;
02094 adj *= ulp(dval(rv));
02095 if (dsign)
02096 dval(rv) += adj;
02097 else
02098 dval(rv) -= adj;
02099 word0(rv) -= P*Exp_msk1;
02100 goto cont;
02101 }
02102 #endif
02103 #endif
02104 adj *= ulp(dval(rv));
02105 if (dsign)
02106 dval(rv) += adj;
02107 else
02108 dval(rv) -= adj;
02109 goto cont;
02110 }
02111 #endif
02112
02113 if (i < 0) {
02114
02115
02116
02117 if (dsign || word1(rv) || word0(rv) & Bndry_mask
02118 #ifdef IEEE_Arith
02119 #ifdef Avoid_Underflow
02120 || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
02121 #else
02122 || (word0(rv) & Exp_mask) <= Exp_msk1
02123 #endif
02124 #endif
02125 ) {
02126 #ifdef SET_INEXACT
02127 if (!delta->x[0] && delta->wds <= 1)
02128 inexact = 0;
02129 #endif
02130 break;
02131 }
02132 if (!delta->x[0] && delta->wds <= 1) {
02133
02134 #ifdef SET_INEXACT
02135 inexact = 0;
02136 #endif
02137 break;
02138 }
02139 delta = lshift(delta,Log2P);
02140 if (cmp(delta, bs) > 0)
02141 goto drop_down;
02142 break;
02143 }
02144 if (i == 0) {
02145
02146 if (dsign) {
02147 if ((word0(rv) & Bndry_mask1) == Bndry_mask1
02148 && word1(rv) == (
02149 #ifdef Avoid_Underflow
02150 (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
02151 ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
02152 #endif
02153 0xffffffff)) {
02154
02155 word0(rv) = (word0(rv) & Exp_mask)
02156 + Exp_msk1
02157 #ifdef IBM
02158 | Exp_msk1 >> 4
02159 #endif
02160 ;
02161 word1(rv) = 0;
02162 #ifdef Avoid_Underflow
02163 dsign = 0;
02164 #endif
02165 break;
02166 }
02167 }
02168 else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
02169 drop_down:
02170
02171 #ifdef Sudden_Underflow
02172 L = word0(rv) & Exp_mask;
02173 #ifdef IBM
02174 if (L < Exp_msk1)
02175 #else
02176 #ifdef Avoid_Underflow
02177 if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
02178 #else
02179 if (L <= Exp_msk1)
02180 #endif
02181 #endif
02182 goto undfl;
02183 L -= Exp_msk1;
02184 #else
02185 #ifdef Avoid_Underflow
02186 if (scale) {
02187 L = word0(rv) & Exp_mask;
02188 if (L <= (2*P+1)*Exp_msk1) {
02189 if (L > (P+2)*Exp_msk1)
02190
02191
02192 break;
02193
02194 goto undfl;
02195 }
02196 }
02197 #endif
02198 L = (word0(rv) & Exp_mask) - Exp_msk1;
02199 #endif
02200 word0(rv) = L | Bndry_mask1;
02201 word1(rv) = 0xffffffff;
02202 #ifdef IBM
02203 goto cont;
02204 #else
02205 break;
02206 #endif
02207 }
02208 #ifndef ROUND_BIASED
02209 if (!(word1(rv) & LSB))
02210 break;
02211 #endif
02212 if (dsign)
02213 dval(rv) += ulp(dval(rv));
02214 #ifndef ROUND_BIASED
02215 else {
02216 dval(rv) -= ulp(dval(rv));
02217 #ifndef Sudden_Underflow
02218 if (!dval(rv))
02219 goto undfl;
02220 #endif
02221 }
02222 #ifdef Avoid_Underflow
02223 dsign = 1 - dsign;
02224 #endif
02225 #endif
02226 break;
02227 }
02228 if ((aadj = ratio(delta, bs)) <= 2.) {
02229 if (dsign)
02230 aadj = aadj1 = 1.;
02231 else if (word1(rv) || word0(rv) & Bndry_mask) {
02232 #ifndef Sudden_Underflow
02233 if (word1(rv) == Tiny1 && !word0(rv))
02234 goto undfl;
02235 #endif
02236 aadj = 1.;
02237 aadj1 = -1.;
02238 }
02239 else {
02240
02241
02242
02243 if (aadj < 2./FLT_RADIX)
02244 aadj = 1./FLT_RADIX;
02245 else
02246 aadj *= 0.5;
02247 aadj1 = -aadj;
02248 }
02249 }
02250 else {
02251 aadj *= 0.5;
02252 aadj1 = dsign ? aadj : -aadj;
02253 #ifdef Check_FLT_ROUNDS
02254 switch(Rounding) {
02255 case 2:
02256 aadj1 -= 0.5;
02257 break;
02258 case 0:
02259 case 3:
02260 aadj1 += 0.5;
02261 }
02262 #else
02263 if (Flt_Rounds == 0)
02264 aadj1 += 0.5;
02265 #endif
02266 }
02267 y = word0(rv) & Exp_mask;
02268
02269
02270
02271 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
02272 dval(rv0) = dval(rv);
02273 word0(rv) -= P*Exp_msk1;
02274 adj = aadj1 * ulp(dval(rv));
02275 dval(rv) += adj;
02276 if ((word0(rv) & Exp_mask) >=
02277 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
02278 if (word0(rv0) == Big0 && word1(rv0) == Big1)
02279 goto ovfl;
02280 word0(rv) = Big0;
02281 word1(rv) = Big1;
02282 goto cont;
02283 }
02284 else
02285 word0(rv) += P*Exp_msk1;
02286 }
02287 else {
02288 #ifdef Avoid_Underflow
02289 if (scale && y <= 2*P*Exp_msk1) {
02290 if (aadj <= 0x7fffffff) {
02291 if ((z = aadj) <= 0)
02292 z = 1;
02293 aadj = z;
02294 aadj1 = dsign ? aadj : -aadj;
02295 }
02296 word0(aadj1) += (2*P+1)*Exp_msk1 - y;
02297 }
02298 adj = aadj1 * ulp(dval(rv));
02299 dval(rv) += adj;
02300 #else
02301 #ifdef Sudden_Underflow
02302 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
02303 dval(rv0) = dval(rv);
02304 word0(rv) += P*Exp_msk1;
02305 adj = aadj1 * ulp(dval(rv));
02306 dval(rv) += adj;
02307 #ifdef IBM
02308 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
02309 #else
02310 if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
02311 #endif
02312 {
02313 if (word0(rv0) == Tiny0
02314 && word1(rv0) == Tiny1)
02315 goto undfl;
02316 word0(rv) = Tiny0;
02317 word1(rv) = Tiny1;
02318 goto cont;
02319 }
02320 else
02321 word0(rv) -= P*Exp_msk1;
02322 }
02323 else {
02324 adj = aadj1 * ulp(dval(rv));
02325 dval(rv) += adj;
02326 }
02327 #else
02328
02329
02330
02331
02332
02333
02334
02335 if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
02336 aadj1 = (double)(int)(aadj + 0.5);
02337 if (!dsign)
02338 aadj1 = -aadj1;
02339 }
02340 adj = aadj1 * ulp(dval(rv));
02341 dval(rv) += adj;
02342 #endif
02343 #endif
02344 }
02345 z = word0(rv) & Exp_mask;
02346 #ifndef SET_INEXACT
02347 #ifdef Avoid_Underflow
02348 if (!scale)
02349 #endif
02350 if (y == z) {
02351
02352 L = (Long)aadj;
02353 aadj -= L;
02354
02355 if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
02356 if (aadj < .4999999 || aadj > .5000001)
02357 break;
02358 }
02359 else if (aadj < .4999999/FLT_RADIX)
02360 break;
02361 }
02362 #endif
02363 cont:
02364 Bfree(bb);
02365 Bfree(bd);
02366 Bfree(bs);
02367 Bfree(delta);
02368 }
02369 #ifdef SET_INEXACT
02370 if (inexact) {
02371 if (!oldinexact) {
02372 word0(rv0) = Exp_1 + (70 << Exp_shift);
02373 word1(rv0) = 0;
02374 dval(rv0) += 1.;
02375 }
02376 }
02377 else if (!oldinexact)
02378 clear_inexact();
02379 #endif
02380 #ifdef Avoid_Underflow
02381 if (scale) {
02382 word0(rv0) = Exp_1 - 2*P*Exp_msk1;
02383 word1(rv0) = 0;
02384 dval(rv) *= dval(rv0);
02385 #ifndef NO_ERRNO
02386
02387 if (word0(rv) == 0 && word1(rv) == 0)
02388 errno = ERANGE;
02389 #endif
02390 }
02391 #endif
02392 #ifdef SET_INEXACT
02393 if (inexact && !(word0(rv) & Exp_mask)) {
02394
02395 dval(rv0) = 1e-300;
02396 dval(rv0) *= dval(rv0);
02397 }
02398 #endif
02399 retfree:
02400 Bfree(bb);
02401 Bfree(bd);
02402 Bfree(bs);
02403 Bfree(bd0);
02404 Bfree(delta);
02405 ret:
02406 if (se)
02407 *se = (char *)s;
02408 return sign ? -dval(rv) : dval(rv);
02409 }
02410
02411 static int
02412 quorem
02413 #ifdef KR_headers
02414 (b, S) Bigint *b, *S;
02415 #else
02416 (Bigint *b, Bigint *S)
02417 #endif
02418 {
02419 int n;
02420 ULong *bx, *bxe, q, *sx, *sxe;
02421 #ifdef ULLong
02422 ULLong borrow, carry, y, ys;
02423 #else
02424 ULong borrow, carry, y, ys;
02425 #ifdef Pack_32
02426 ULong si, z, zs;
02427 #endif
02428 #endif
02429
02430 n = S->wds;
02431 #ifdef DEBUG
02432 if (b->wds > n)
02433 Bug("oversize b in quorem");
02434 #endif
02435 if (b->wds < n)
02436 return 0;
02437 sx = S->x;
02438 sxe = sx + --n;
02439 bx = b->x;
02440 bxe = bx + n;
02441 q = *bxe / (*sxe + 1);
02442 #ifdef DEBUG
02443 if (q > 9)
02444 Bug("oversized quotient in quorem");
02445 #endif
02446 if (q) {
02447 borrow = 0;
02448 carry = 0;
02449 do {
02450 #ifdef ULLong
02451 ys = *sx++ * (ULLong)q + carry;
02452 carry = ys >> 32;
02453 y = *bx - (ys & FFFFFFFF) - borrow;
02454 borrow = y >> 32 & (ULong)1;
02455 *bx++ = y & FFFFFFFF;
02456 #else
02457 #ifdef Pack_32
02458 si = *sx++;
02459 ys = (si & 0xffff) * q + carry;
02460 zs = (si >> 16) * q + (ys >> 16);
02461 carry = zs >> 16;
02462 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
02463 borrow = (y & 0x10000) >> 16;
02464 z = (*bx >> 16) - (zs & 0xffff) - borrow;
02465 borrow = (z & 0x10000) >> 16;
02466 Storeinc(bx, z, y);
02467 #else
02468 ys = *sx++ * q + carry;
02469 carry = ys >> 16;
02470 y = *bx - (ys & 0xffff) - borrow;
02471 borrow = (y & 0x10000) >> 16;
02472 *bx++ = y & 0xffff;
02473 #endif
02474 #endif
02475 }
02476 while(sx <= sxe);
02477 if (!*bxe) {
02478 bx = b->x;
02479 while(--bxe > bx && !*bxe)
02480 --n;
02481 b->wds = n;
02482 }
02483 }
02484 if (cmp(b, S) >= 0) {
02485 q++;
02486 borrow = 0;
02487 carry = 0;
02488 bx = b->x;
02489 sx = S->x;
02490 do {
02491 #ifdef ULLong
02492 ys = *sx++ + carry;
02493 carry = ys >> 32;
02494 y = *bx - (ys & FFFFFFFF) - borrow;
02495 borrow = y >> 32 & (ULong)1;
02496 *bx++ = y & FFFFFFFF;
02497 #else
02498 #ifdef Pack_32
02499 si = *sx++;
02500 ys = (si & 0xffff) + carry;
02501 zs = (si >> 16) + (ys >> 16);
02502 carry = zs >> 16;
02503 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
02504 borrow = (y & 0x10000) >> 16;
02505 z = (*bx >> 16) - (zs & 0xffff) - borrow;
02506 borrow = (z & 0x10000) >> 16;
02507 Storeinc(bx, z, y);
02508 #else
02509 ys = *sx++ + carry;
02510 carry = ys >> 16;
02511 y = *bx - (ys & 0xffff) - borrow;
02512 borrow = (y & 0x10000) >> 16;
02513 *bx++ = y & 0xffff;
02514 #endif
02515 #endif
02516 }
02517 while(sx <= sxe);
02518 bx = b->x;
02519 bxe = bx + n;
02520 if (!*bxe) {
02521 while(--bxe > bx && !*bxe)
02522 --n;
02523 b->wds = n;
02524 }
02525 }
02526 return q;
02527 }
02528
02529 #ifndef MULTIPLE_THREADS
02530 static char *dtoa_result;
02531 #endif
02532
02533 static char *
02534 #ifdef KR_headers
02535 rv_alloc(i) int i;
02536 #else
02537 rv_alloc(int i)
02538 #endif
02539 {
02540 int j, k, *r;
02541
02542 j = sizeof(ULong);
02543 for(k = 0;
02544 sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
02545 j <<= 1)
02546 k++;
02547 r = (int*)Balloc(k);
02548 *r = k;
02549 return
02550 #ifndef MULTIPLE_THREADS
02551 dtoa_result =
02552 #endif
02553 (char *)(r+1);
02554 }
02555
02556 static char *
02557 #ifdef KR_headers
02558 nrv_alloc(s, rve, n) char *s, **rve; int n;
02559 #else
02560 nrv_alloc(const char *s, char **rve, int n)
02561 #endif
02562 {
02563 char *rv, *t;
02564
02565 t = rv = rv_alloc(n);
02566 while ((*t = *s++)) t++;
02567 if (rve)
02568 *rve = t;
02569 return rv;
02570 }
02571
02572
02573
02574
02575
02576
02577
02578 void
02579 #ifdef KR_headers
02580 freedtoa(s) char *s;
02581 #else
02582 freedtoa(char *s)
02583 #endif
02584 {
02585 Bigint *b = (Bigint *)((int *)s - 1);
02586 b->maxwds = 1 << (b->k = *(int*)b);
02587 Bfree(b);
02588 #ifndef MULTIPLE_THREADS
02589 if (s == dtoa_result)
02590 dtoa_result = 0;
02591 #endif
02592 }
02593
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628 char *
02629 dtoa
02630 #ifdef KR_headers
02631 (d, mode, ndigits, decpt, sign, rve)
02632 double d; int mode, ndigits, *decpt, *sign; char **rve;
02633 #else
02634 (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
02635 #endif
02636 {
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
02672 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
02673 spec_case, try_quick, bias_round_up;
02674 Long L;
02675 #ifndef Sudden_Underflow
02676 int denorm;
02677 ULong x;
02678 #endif
02679 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
02680 double d2, ds, eps;
02681 char *s, *s0;
02682 #ifdef Honor_FLT_ROUNDS
02683 int rounding;
02684 #endif
02685 #ifdef SET_INEXACT
02686 int inexact, oldinexact;
02687 #endif
02688
02689
02690 bias_round_up = mode == 2 || mode == 3;
02691
02692 ilim = ilim1 = 0;
02693
02694 #ifndef MULTIPLE_THREADS
02695 if (dtoa_result) {
02696 freedtoa(dtoa_result);
02697 dtoa_result = 0;
02698 }
02699 #endif
02700
02701 if (word0(d) & Sign_bit) {
02702
02703 *sign = 1;
02704 word0(d) &= ~Sign_bit;
02705 }
02706 else
02707 *sign = 0;
02708
02709 #if defined(IEEE_Arith) + defined(VAX)
02710 #ifdef IEEE_Arith
02711 if ((word0(d) & Exp_mask) == Exp_mask)
02712 #else
02713 if (word0(d) == 0x8000)
02714 #endif
02715 {
02716
02717 *decpt = 9999;
02718 #ifdef IEEE_Arith
02719 if (!word1(d) && !(word0(d) & 0xfffff))
02720 return nrv_alloc("Infinity", rve, 8);
02721 #endif
02722 return nrv_alloc("NaN", rve, 3);
02723 }
02724 #endif
02725 #ifdef IBM
02726 dval(d) += 0;
02727 #endif
02728 if (!dval(d)) {
02729 *decpt = 1;
02730 return nrv_alloc("0", rve, 1);
02731 }
02732
02733 #ifdef SET_INEXACT
02734 try_quick = oldinexact = get_inexact();
02735 inexact = 1;
02736 #endif
02737 #ifdef Honor_FLT_ROUNDS
02738 if ((rounding = Flt_Rounds) >= 2) {
02739 if (*sign)
02740 rounding = rounding == 2 ? 0 : 2;
02741 else
02742 if (rounding != 2)
02743 rounding = 0;
02744 }
02745 #endif
02746
02747 b = d2b(dval(d), &be, &bbits);
02748 #ifdef Sudden_Underflow
02749 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
02750 #else
02751 if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
02752 #endif
02753 dval(d2) = dval(d);
02754 word0(d2) &= Frac_mask1;
02755 word0(d2) |= Exp_11;
02756 #ifdef IBM
02757 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
02758 dval(d2) /= 1 << j;
02759 #endif
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783 i -= Bias;
02784 #ifdef IBM
02785 i <<= 2;
02786 i += j;
02787 #endif
02788 #ifndef Sudden_Underflow
02789 denorm = 0;
02790 }
02791 else {
02792
02793
02794 i = bbits + be + (Bias + (P-1) - 1);
02795 x = i > 32 ? (word0(d) << (64 - i)) | (word1(d) >> (i - 32))
02796 : word1(d) << (32 - i);
02797 dval(d2) = x;
02798 word0(d2) -= 31*Exp_msk1;
02799 i -= (Bias + (P-1) - 1) + 1;
02800 denorm = 1;
02801 }
02802 #endif
02803 ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
02804 k = (int)ds;
02805 if (ds < 0. && ds != k)
02806 k--;
02807 k_check = 1;
02808 if (k >= 0 && k <= Ten_pmax) {
02809 if (dval(d) < tens[k])
02810 k--;
02811 k_check = 0;
02812 }
02813 j = bbits - i - 1;
02814 if (j >= 0) {
02815 b2 = 0;
02816 s2 = j;
02817 }
02818 else {
02819 b2 = -j;
02820 s2 = 0;
02821 }
02822 if (k >= 0) {
02823 b5 = 0;
02824 s5 = k;
02825 s2 += k;
02826 }
02827 else {
02828 b2 -= k;
02829 b5 = -k;
02830 s5 = 0;
02831 }
02832 if (mode < 0 || mode > 9)
02833 mode = 0;
02834
02835 #ifndef SET_INEXACT
02836 #ifdef Check_FLT_ROUNDS
02837 try_quick = Rounding == 1;
02838 #else
02839 try_quick = 1;
02840 #endif
02841 #endif
02842
02843 if (mode > 5) {
02844 mode -= 4;
02845 try_quick = 0;
02846 }
02847 leftright = 1;
02848 switch(mode) {
02849 case 0:
02850 case 1:
02851 ilim = ilim1 = -1;
02852 i = 18;
02853 ndigits = 0;
02854 break;
02855 case 2:
02856 leftright = 0;
02857
02858 case 4:
02859 if (ndigits <= 0)
02860 ndigits = 1;
02861 ilim = ilim1 = i = ndigits;
02862 break;
02863 case 3:
02864 leftright = 0;
02865
02866 case 5:
02867 i = ndigits + k + 1;
02868 ilim = i;
02869 ilim1 = i - 1;
02870 if (i <= 0)
02871 i = 1;
02872 }
02873 s = s0 = rv_alloc(i);
02874
02875 #ifdef Honor_FLT_ROUNDS
02876 if (mode > 1 && rounding != 1)
02877 leftright = 0;
02878 #endif
02879
02880 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
02881
02882
02883
02884 i = 0;
02885 dval(d2) = dval(d);
02886 k0 = k;
02887 ilim0 = ilim;
02888 ieps = 2;
02889 if (k > 0) {
02890 ds = tens[k&0xf];
02891 j = k >> 4;
02892 if (j & Bletch) {
02893
02894 j &= Bletch - 1;
02895 dval(d) /= bigtens[n_bigtens-1];
02896 ieps++;
02897 }
02898 for(; j; j >>= 1, i++)
02899 if (j & 1) {
02900 ieps++;
02901 ds *= bigtens[i];
02902 }
02903 dval(d) /= ds;
02904 }
02905 else if ((j1 = -k)) {
02906 dval(d) *= tens[j1 & 0xf];
02907 for(j = j1 >> 4; j; j >>= 1, i++)
02908 if (j & 1) {
02909 ieps++;
02910 dval(d) *= bigtens[i];
02911 }
02912 }
02913 if (k_check && dval(d) < 1. && ilim > 0) {
02914 if (ilim1 <= 0)
02915 goto fast_failed;
02916 ilim = ilim1;
02917 k--;
02918 dval(d) *= 10.;
02919 ieps++;
02920 }
02921 dval(eps) = ieps*dval(d) + 7.;
02922 word0(eps) -= (P-1)*Exp_msk1;
02923 if (ilim == 0) {
02924 S = mhi = 0;
02925 dval(d) -= 5.;
02926 if (dval(d) > dval(eps))
02927 goto one_digit;
02928 if (dval(d) < -dval(eps))
02929 goto no_digits;
02930 goto fast_failed;
02931 }
02932 #ifndef No_leftright
02933 if (leftright) {
02934
02935
02936
02937 dval(eps) = 0.5/tens[ilim-1] - dval(eps);
02938 for(i = 0;;) {
02939 L = dval(d);
02940 dval(d) -= L;
02941 *s++ = '0' + (int)L;
02942 if (dval(d) < dval(eps))
02943 goto ret1;
02944 if (1. - dval(d) < dval(eps))
02945 goto bump_up;
02946 if (++i >= ilim)
02947 break;
02948 dval(eps) *= 10.;
02949 dval(d) *= 10.;
02950 }
02951 }
02952 else {
02953 #endif
02954
02955 dval(eps) *= tens[ilim-1];
02956 for(i = 1;; i++, dval(d) *= 10.) {
02957 L = (Long)(dval(d));
02958 if (!(dval(d) -= L))
02959 ilim = i;
02960 *s++ = '0' + (int)L;
02961 if (i == ilim) {
02962 if (dval(d) > 0.5 + dval(eps))
02963 goto bump_up;
02964 else if (dval(d) < 0.5 - dval(eps)) {
02965 while(*--s == '0');
02966 s++;
02967 goto ret1;
02968 }
02969 break;
02970 }
02971 }
02972 #ifndef No_leftright
02973 }
02974 #endif
02975 fast_failed:
02976 s = s0;
02977 dval(d) = dval(d2);
02978 k = k0;
02979 ilim = ilim0;
02980 }
02981
02982
02983
02984 if (be >= 0 && k <= Int_max) {
02985
02986 ds = tens[k];
02987 if (ndigits < 0 && ilim <= 0) {
02988 S = mhi = 0;
02989 if (ilim < 0 || dval(d) < 5*ds || ((dval(d) == 5*ds) && !bias_round_up))
02990 goto no_digits;
02991 goto one_digit;
02992 }
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003 for(i = 1; i <= k+1; i++, dval(d) *= 10.) {
03004 L = (Long)(dval(d) / ds);
03005 dval(d) -= L*ds;
03006 #ifdef Check_FLT_ROUNDS
03007
03008 if (dval(d) < 0) {
03009 L--;
03010 dval(d) += ds;
03011 }
03012 #endif
03013 *s++ = '0' + (int)L;
03014 if (!dval(d)) {
03015 #ifdef SET_INEXACT
03016 inexact = 0;
03017 #endif
03018 break;
03019 }
03020 if (i == ilim) {
03021 #ifdef Honor_FLT_ROUNDS
03022 if (mode > 1)
03023 switch(rounding) {
03024 case 0: goto ret1;
03025 case 2: goto bump_up;
03026 }
03027 #endif
03028 dval(d) += dval(d);
03029 if (dval(d) > ds || (dval(d) == ds && ((L & 1) || bias_round_up))) {
03030 bump_up:
03031 while(*--s == '9')
03032 if (s == s0) {
03033 k++;
03034 *s = '0';
03035 break;
03036 }
03037 ++*s++;
03038 }
03039 break;
03040 }
03041 }
03042 goto ret1;
03043 }
03044
03045 m2 = b2;
03046 m5 = b5;
03047 mhi = mlo = 0;
03048 if (leftright) {
03049 i =
03050 #ifndef Sudden_Underflow
03051 denorm ? be + (Bias + (P-1) - 1 + 1) :
03052 #endif
03053 #ifdef IBM
03054 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
03055 #else
03056 1 + P - bbits;
03057 #endif
03058 b2 += i;
03059 s2 += i;
03060 mhi = i2b(1);
03061 }
03062 if (m2 > 0 && s2 > 0) {
03063 i = m2 < s2 ? m2 : s2;
03064 b2 -= i;
03065 m2 -= i;
03066 s2 -= i;
03067 }
03068 if (b5 > 0) {
03069 if (leftright) {
03070 if (m5 > 0) {
03071 mhi = pow5mult(mhi, m5);
03072 b1 = mult(mhi, b);
03073 Bfree(b);
03074 b = b1;
03075 }
03076 if ((j = b5 - m5))
03077 b = pow5mult(b, j);
03078 }
03079 else
03080 b = pow5mult(b, b5);
03081 }
03082 S = i2b(1);
03083 if (s5 > 0)
03084 S = pow5mult(S, s5);
03085
03086
03087
03088 spec_case = 0;
03089 if ((mode < 2 || leftright)
03090 #ifdef Honor_FLT_ROUNDS
03091 && rounding == 1
03092 #endif
03093 ) {
03094 if (!word1(d) && !(word0(d) & Bndry_mask)
03095 #ifndef Sudden_Underflow
03096 && word0(d) & (Exp_mask & ~Exp_msk1)
03097 #endif
03098 ) {
03099
03100 b2 += Log2P;
03101 s2 += Log2P;
03102 spec_case = 1;
03103 }
03104 }
03105
03106
03107
03108
03109
03110
03111
03112
03113 #ifdef Pack_32
03114 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f))
03115 i = 32 - i;
03116 #else
03117 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf))
03118 i = 16 - i;
03119 #endif
03120 if (i > 4) {
03121 i -= 4;
03122 b2 += i;
03123 m2 += i;
03124 s2 += i;
03125 }
03126 else if (i < 4) {
03127 i += 28;
03128 b2 += i;
03129 m2 += i;
03130 s2 += i;
03131 }
03132 if (b2 > 0)
03133 b = lshift(b, b2);
03134 if (s2 > 0)
03135 S = lshift(S, s2);
03136 if (k_check) {
03137 if (cmp(b,S) < 0) {
03138 k--;
03139 b = multadd(b, 10, 0);
03140 if (leftright)
03141 mhi = multadd(mhi, 10, 0);
03142 ilim = ilim1;
03143 }
03144 }
03145 if (ilim <= 0 && (mode == 3 || mode == 5)) {
03146 S = multadd(S, 5, 0);
03147 if (ilim < 0 || cmp(b, S) < 0 || ((cmp(b, S) == 0) && !bias_round_up)) {
03148
03149 no_digits:
03150 k = -1 - ndigits;
03151 goto ret;
03152 }
03153 one_digit:
03154 *s++ = '1';
03155 k++;
03156 goto ret;
03157 }
03158 if (leftright) {
03159 if (m2 > 0)
03160 mhi = lshift(mhi, m2);
03161
03162
03163
03164
03165
03166 mlo = mhi;
03167 if (spec_case) {
03168 mhi = Balloc(mhi->k);
03169 Bcopy(mhi, mlo);
03170 mhi = lshift(mhi, Log2P);
03171 }
03172
03173 for(i = 1;;i++) {
03174 dig = quorem(b,S) + '0';
03175
03176
03177
03178 j = cmp(b, mlo);
03179 delta = diff(S, mhi);
03180 j1 = delta->sign ? 1 : cmp(b, delta);
03181 Bfree(delta);
03182 #ifndef ROUND_BIASED
03183 if (j1 == 0 && mode != 1 && !(word1(d) & 1)
03184 #ifdef Honor_FLT_ROUNDS
03185 && rounding >= 1
03186 #endif
03187 ) {
03188 if (dig == '9')
03189 goto round_9_up;
03190 if (j > 0)
03191 dig++;
03192 #ifdef SET_INEXACT
03193 else if (!b->x[0] && b->wds <= 1)
03194 inexact = 0;
03195 #endif
03196 *s++ = dig;
03197 goto ret;
03198 }
03199 #endif
03200 if (j < 0 || (j == 0 && mode != 1
03201 #ifndef ROUND_BIASED
03202 && !(word1(d) & 1)
03203 #endif
03204 )) {
03205 if (!b->x[0] && b->wds <= 1) {
03206 #ifdef SET_INEXACT
03207 inexact = 0;
03208 #endif
03209 goto accept_dig;
03210 }
03211 #ifdef Honor_FLT_ROUNDS
03212 if (mode > 1)
03213 switch(rounding) {
03214 case 0: goto accept_dig;
03215 case 2: goto keep_dig;
03216 }
03217 #endif
03218 if (j1 > 0) {
03219 b = lshift(b, 1);
03220 j1 = cmp(b, S);
03221 if ((j1 > 0 || (j1 == 0 && ((dig & 1) || bias_round_up)))
03222 && dig++ == '9')
03223 goto round_9_up;
03224 }
03225 accept_dig:
03226 *s++ = dig;
03227 goto ret;
03228 }
03229 if (j1 > 0) {
03230 #ifdef Honor_FLT_ROUNDS
03231 if (!rounding)
03232 goto accept_dig;
03233 #endif
03234 if (dig == '9') {
03235 round_9_up:
03236 *s++ = '9';
03237 goto roundoff;
03238 }
03239 *s++ = dig + 1;
03240 goto ret;
03241 }
03242 #ifdef Honor_FLT_ROUNDS
03243 keep_dig:
03244 #endif
03245 *s++ = dig;
03246 if (i == ilim)
03247 break;
03248 b = multadd(b, 10, 0);
03249 if (mlo == mhi)
03250 mlo = mhi = multadd(mhi, 10, 0);
03251 else {
03252 mlo = multadd(mlo, 10, 0);
03253 mhi = multadd(mhi, 10, 0);
03254 }
03255 }
03256 }
03257 else
03258 for(i = 1;; i++) {
03259 *s++ = dig = quorem(b,S) + '0';
03260 if (!b->x[0] && b->wds <= 1) {
03261 #ifdef SET_INEXACT
03262 inexact = 0;
03263 #endif
03264 goto ret;
03265 }
03266 if (i >= ilim)
03267 break;
03268 b = multadd(b, 10, 0);
03269 }
03270
03271
03272
03273 #ifdef Honor_FLT_ROUNDS
03274 switch(rounding) {
03275 case 0: goto trimzeros;
03276 case 2: goto roundoff;
03277 }
03278 #endif
03279 b = lshift(b, 1);
03280 j = cmp(b, S);
03281 if (j > 0 || (j == 0 && ((dig & 1) || bias_round_up))) {
03282 roundoff:
03283 while(*--s == '9')
03284 if (s == s0) {
03285 k++;
03286 *s++ = '1';
03287 goto ret;
03288 }
03289 ++*s++;
03290 }
03291 else {
03292
03293 while(*--s == '0');
03294 s++;
03295 }
03296 ret:
03297 Bfree(S);
03298 if (mhi) {
03299 if (mlo && mlo != mhi)
03300 Bfree(mlo);
03301 Bfree(mhi);
03302 }
03303 ret1:
03304 #ifdef SET_INEXACT
03305 if (inexact) {
03306 if (!oldinexact) {
03307 word0(d) = Exp_1 + (70 << Exp_shift);
03308 word1(d) = 0;
03309 dval(d) += 1.;
03310 }
03311 }
03312 else if (!oldinexact)
03313 clear_inexact();
03314 #endif
03315 Bfree(b);
03316 *s = 0;
03317 *decpt = k + 1;
03318 if (rve)
03319 *rve = s;
03320 return s0;
03321 }
03322 #ifdef __cplusplus
03323 }
03324 #endif