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