00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00021 #include "OSConfig.h"
00022 #include "OSdtoa.h"
00023 #include "OSParameters.h"
00024
00025 #ifdef WORDS_BIGENDIAN
00026 #define IEEE_MC68k
00027 #else
00028 #define IEEE_8087
00029 #endif
00030
00031 #define INFNAN_CHECK
00032
00033 #define NO_LONG_LONG
00034 #define Just_16
00035
00036 #if SIZEOF_LONG == 2*SIZEOF_INT
00037 #define Long int
00038 #define Intcast (int)(long)
00039 #endif
00040
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
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 #ifndef Long
00236 #define Long long
00237 #endif
00238 #ifndef ULong
00239 typedef unsigned Long ULong;
00240 #endif
00241
00242
00243
00244 #ifdef DEBUG
00245 #include "stdio.h"
00246 #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
00247 #endif
00248
00249 #include "stdlib.h"
00250 #include "string.h"
00251
00252 #ifdef USE_LOCALE
00253 #include "locale.h"
00254 #endif
00255
00256 #ifdef Honor_FLT_ROUNDS
00257 #ifndef Trust_FLT_ROUNDS
00258 #include <fenv.h>
00259 #endif
00260 #endif
00261
00262 #ifdef MALLOC
00263 #ifdef KR_headers
00264 extern char *MALLOC();
00265 #else
00266 extern void *MALLOC(size_t);
00267 #endif
00268 #else
00269 #define MALLOC malloc
00270 #endif
00271
00272 #ifndef Omit_Private_Memory
00273 #ifndef PRIVATE_MEM
00274 #define PRIVATE_MEM 2304
00275 #endif
00276 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
00277 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
00278 #endif
00279
00280 #undef IEEE_Arith
00281 #undef Avoid_Underflow
00282 #ifdef IEEE_MC68k
00283 #define IEEE_Arith
00284 #endif
00285 #ifdef IEEE_8087
00286 #define IEEE_Arith
00287 #endif
00288
00289 #ifdef IEEE_Arith
00290 #ifndef NO_INFNAN_CHECK
00291 #undef INFNAN_CHECK
00292 #define INFNAN_CHECK
00293 #endif
00294 #else
00295 #undef INFNAN_CHECK
00296 #define NO_STRTOD_BIGCOMP
00297 #endif
00298
00299 #include "errno.h"
00300
00301 #ifdef Bad_float_h
00302
00303 #ifdef IEEE_Arith
00304 #define DBL_DIG 15
00305 #define DBL_MAX_10_EXP 308
00306 #define DBL_MAX_EXP 1024
00307 #define FLT_RADIX 2
00308 #endif
00309
00310 #ifdef IBM
00311 #define DBL_DIG 16
00312 #define DBL_MAX_10_EXP 75
00313 #define DBL_MAX_EXP 63
00314 #define FLT_RADIX 16
00315 #define DBL_MAX 7.2370055773322621e+75
00316 #endif
00317
00318 #ifdef VAX
00319 #define DBL_DIG 16
00320 #define DBL_MAX_10_EXP 38
00321 #define DBL_MAX_EXP 127
00322 #define FLT_RADIX 2
00323 #define DBL_MAX 1.7014118346046923e+38
00324 #endif
00325
00326 #ifndef LONG_MAX
00327 #define LONG_MAX 2147483647
00328 #endif
00329
00330 #else
00331 #include "float.h"
00332 #endif
00333
00334 #ifndef __MATH_H__
00335 #include "math.h"
00336 #endif
00337
00338 #ifdef __cplusplus
00339 extern "C" {
00340 #endif
00341
00342 #ifndef CONST
00343 #ifdef KR_headers
00344 #define CONST
00345 #else
00346 #define CONST const
00347 #endif
00348 #endif
00349
00350
00351
00352
00353
00354 typedef union { double d; ULong L[2]; } U;
00355
00356 #ifdef IEEE_8087
00357 #define word0(x) (x)->L[1]
00358 #define word1(x) (x)->L[0]
00359 #else
00360 #define word0(x) (x)->L[0]
00361 #define word1(x) (x)->L[1]
00362 #endif
00363 #define dval(x) (x)->d
00364
00365 #ifndef STRTOD_DIGLIM
00366 #define STRTOD_DIGLIM 40
00367 #endif
00368
00369 #ifdef DIGLIM_DEBUG
00370 extern int strtod_diglim;
00371 #else
00372 #define strtod_diglim STRTOD_DIGLIM
00373 #endif
00374
00375
00376
00377
00378
00379 #if defined(IEEE_8087) + defined(VAX)
00380 #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
00381 ((unsigned short *)a)[0] = (unsigned short)c, a++)
00382 #else
00383 #define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
00384 ((unsigned short *)a)[1] = (unsigned short)c, a++)
00385 #endif
00386
00387
00388
00389
00390
00391
00392
00393 #ifdef IEEE_Arith
00394 #define Exp_shift 20
00395 #define Exp_shift1 20
00396 #define Exp_msk1 0x100000
00397 #define Exp_msk11 0x100000
00398 #define Exp_mask 0x7ff00000
00399 #define P 53
00400 #define Nbits 53
00401 #define Bias 1023
00402 #define Emax 1023
00403 #define Emin (-1022)
00404 #define Exp_1 0x3ff00000
00405 #define Exp_11 0x3ff00000
00406 #define Ebits 11
00407 #define Frac_mask 0xfffff
00408 #define Frac_mask1 0xfffff
00409 #define Ten_pmax 22
00410 #define Bletch 0x10
00411 #define Bndry_mask 0xfffff
00412 #define Bndry_mask1 0xfffff
00413 #define LSB 1
00414 #define Sign_bit 0x80000000
00415 #define Log2P 1
00416 #define Tiny0 0
00417 #define Tiny1 1
00418 #define Quick_max 14
00419 #define Int_max 14
00420 #ifndef NO_IEEE_Scale
00421 #define Avoid_Underflow
00422 #ifdef Flush_Denorm
00423 #undef Sudden_Underflow
00424 #endif
00425 #endif
00426
00427 #ifndef Flt_Rounds
00428 #ifdef FLT_ROUNDS
00429 #define Flt_Rounds FLT_ROUNDS
00430 #else
00431 #define Flt_Rounds 1
00432 #endif
00433 #endif
00434
00435 #ifdef Honor_FLT_ROUNDS
00436 #undef Check_FLT_ROUNDS
00437 #define Check_FLT_ROUNDS
00438 #else
00439 #define Rounding Flt_Rounds
00440 #endif
00441
00442 #else
00443 #undef Check_FLT_ROUNDS
00444 #undef Honor_FLT_ROUNDS
00445 #undef SET_INEXACT
00446 #undef Sudden_Underflow
00447 #define Sudden_Underflow
00448 #ifdef IBM
00449 #undef Flt_Rounds
00450 #define Flt_Rounds 0
00451 #define Exp_shift 24
00452 #define Exp_shift1 24
00453 #define Exp_msk1 0x1000000
00454 #define Exp_msk11 0x1000000
00455 #define Exp_mask 0x7f000000
00456 #define P 14
00457 #define Nbits 56
00458 #define Bias 65
00459 #define Emax 248
00460 #define Emin (-260)
00461 #define Exp_1 0x41000000
00462 #define Exp_11 0x41000000
00463 #define Ebits 8
00464 #define Frac_mask 0xffffff
00465 #define Frac_mask1 0xffffff
00466 #define Bletch 4
00467 #define Ten_pmax 22
00468 #define Bndry_mask 0xefffff
00469 #define Bndry_mask1 0xffffff
00470 #define LSB 1
00471 #define Sign_bit 0x80000000
00472 #define Log2P 4
00473 #define Tiny0 0x100000
00474 #define Tiny1 0
00475 #define Quick_max 14
00476 #define Int_max 15
00477 #else
00478 #undef Flt_Rounds
00479 #define Flt_Rounds 1
00480 #define Exp_shift 23
00481 #define Exp_shift1 7
00482 #define Exp_msk1 0x80
00483 #define Exp_msk11 0x800000
00484 #define Exp_mask 0x7f80
00485 #define P 56
00486 #define Nbits 56
00487 #define Bias 129
00488 #define Emax 126
00489 #define Emin (-129)
00490 #define Exp_1 0x40800000
00491 #define Exp_11 0x4080
00492 #define Ebits 8
00493 #define Frac_mask 0x7fffff
00494 #define Frac_mask1 0xffff007f
00495 #define Ten_pmax 24
00496 #define Bletch 2
00497 #define Bndry_mask 0xffff007f
00498 #define Bndry_mask1 0xffff007f
00499 #define LSB 0x10000
00500 #define Sign_bit 0x8000
00501 #define Log2P 1
00502 #define Tiny0 0x80
00503 #define Tiny1 0
00504 #define Quick_max 15
00505 #define Int_max 15
00506 #endif
00507 #endif
00508
00509 #ifndef IEEE_Arith
00510 #define ROUND_BIASED
00511 #else
00512 #ifdef ROUND_BIASED_without_Round_Up
00513 #undef ROUND_BIASED
00514 #define ROUND_BIASED
00515 #endif
00516 #endif
00517
00518 #ifdef RND_PRODQUOT
00519 #define rounded_product(a,b) a = rnd_prod(a, b)
00520 #define rounded_quotient(a,b) a = rnd_quot(a, b)
00521 #ifdef KR_headers
00522 extern double rnd_prod(), rnd_quot();
00523 #else
00524 extern double rnd_prod(double, double), rnd_quot(double, double);
00525 #endif
00526 #else
00527 #define rounded_product(a,b) a *= b
00528 #define rounded_quotient(a,b) a /= b
00529 #endif
00530
00531 #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
00532 #define Big1 0xffffffff
00533
00534 #ifndef Pack_32
00535 #define Pack_32
00536 #endif
00537
00538 typedef struct BCinfo BCinfo;
00539 struct
00540 BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; };
00541
00542 #ifdef KR_headers
00543 #define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff)
00544 #else
00545 #define FFFFFFFF 0xffffffffUL
00546 #endif
00547
00548 #ifdef NO_LONG_LONG
00549 #undef ULLong
00550 #ifdef Just_16
00551 #undef Pack_32
00552
00553
00554
00555
00556
00557 #endif
00558 #else
00559 #ifndef Llong
00560 #define Llong long long
00561 #endif
00562 #ifndef ULLong
00563 #define ULLong unsigned Llong
00564 #endif
00565 #endif
00566
00567 #ifndef MULTIPLE_THREADS
00568 #define ACQUIRE_DTOA_LOCK(n)
00569 #define FREE_DTOA_LOCK(n)
00570 #endif
00571
00572 #define Kmax 7
00573
00574 #ifdef __cplusplus
00575 extern "C" double os_strtod(const char *s00, char **se);
00576 extern "C" char *os_dtoa(double d, int mode, int ndigits,
00577 int *decpt, int *sign, char **rve);
00578 #endif
00579
00580 struct
00581 Bigint {
00582 struct Bigint *next;
00583 int k, maxwds, sign, wds;
00584 ULong x[1];
00585 };
00586
00587 typedef struct Bigint Bigint;
00588
00589 static Bigint *freelist[Kmax+1];
00590
00591 static Bigint *
00592 Balloc
00593 #ifdef KR_headers
00594 (k) int k;
00595 #else
00596 (int k)
00597 #endif
00598 {
00599 int x;
00600 Bigint *rv;
00601 #ifndef Omit_Private_Memory
00602 unsigned int len;
00603 #endif
00604
00605 ACQUIRE_DTOA_LOCK(0);
00606
00607
00608 if (k <= Kmax && (rv = freelist[k]))
00609 freelist[k] = rv->next;
00610 else {
00611 x = 1 << k;
00612 #ifdef Omit_Private_Memory
00613 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
00614 #else
00615 len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
00616 /sizeof(double);
00617 if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
00618 rv = (Bigint*)pmem_next;
00619 pmem_next += len;
00620 }
00621 else
00622 rv = (Bigint*)MALLOC(len*sizeof(double));
00623 #endif
00624 rv->k = k;
00625 rv->maxwds = x;
00626 }
00627 FREE_DTOA_LOCK(0);
00628 rv->sign = rv->wds = 0;
00629 return rv;
00630 }
00631
00632 static void
00633 Bfree
00634 #ifdef KR_headers
00635 (v) Bigint *v;
00636 #else
00637 (Bigint *v)
00638 #endif
00639 {
00640 if (v) {
00641 if (v->k > Kmax)
00642 #ifdef FREE
00643 FREE((void*)v);
00644 #else
00645 free((void*)v);
00646 #endif
00647 else {
00648 ACQUIRE_DTOA_LOCK(0);
00649 v->next = freelist[v->k];
00650 freelist[v->k] = v;
00651 FREE_DTOA_LOCK(0);
00652 }
00653 }
00654 }
00655
00656 #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
00657 y->wds*sizeof(Long) + 2*sizeof(int))
00658
00659 static Bigint *
00660 multadd
00661 #ifdef KR_headers
00662 (b, m, a) Bigint *b; int m, a;
00663 #else
00664 (Bigint *b, int m, int a)
00665 #endif
00666 {
00667 int i, wds;
00668 #ifdef ULLong
00669 ULong *x;
00670 ULLong carry, y;
00671 #else
00672 ULong carry, *x, y;
00673 #ifdef Pack_32
00674 ULong xi, z;
00675 #endif
00676 #endif
00677 Bigint *b1;
00678
00679 wds = b->wds;
00680 x = b->x;
00681 i = 0;
00682 carry = a;
00683 do {
00684 #ifdef ULLong
00685 y = *x * (ULLong)m + carry;
00686 carry = y >> 32;
00687 *x++ = y & FFFFFFFF;
00688 #else
00689 #ifdef Pack_32
00690 xi = *x;
00691 y = (xi & 0xffff) * m + carry;
00692 z = (xi >> 16) * m + (y >> 16);
00693 carry = z >> 16;
00694 *x++ = (z << 16) + (y & 0xffff);
00695 #else
00696 y = *x * m + carry;
00697 carry = y >> 16;
00698 *x++ = y & 0xffff;
00699 #endif
00700 #endif
00701 }
00702 while(++i < wds);
00703 if (carry) {
00704 if (wds >= b->maxwds) {
00705 b1 = Balloc(b->k+1);
00706 Bcopy(b1, b);
00707 Bfree(b);
00708 b = b1;
00709 }
00710 b->x[wds++] = carry;
00711 b->wds = wds;
00712 }
00713 return b;
00714 }
00715
00716 static Bigint *
00717 s2b
00718 #ifdef KR_headers
00719 (s, nd0, nd, y9, dplen) CONST char *s; int nd0, nd, dplen; ULong y9;
00720 #else
00721 (const char *s, int nd0, int nd, ULong y9, int dplen)
00722 #endif
00723 {
00724 Bigint *b;
00725 int i, k;
00726 Long x, y;
00727
00728 x = (nd + 8) / 9;
00729 for(k = 0, y = 1; x > y; y <<= 1, k++) ;
00730 #ifdef Pack_32
00731 b = Balloc(k);
00732 b->x[0] = y9;
00733 b->wds = 1;
00734 #else
00735 b = Balloc(k+1);
00736 b->x[0] = y9 & 0xffff;
00737 b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
00738 #endif
00739
00740 i = 9;
00741 if (9 < nd0) {
00742 s += 9;
00743 do b = multadd(b, 10, *s++ - '0');
00744 while(++i < nd0);
00745 s += dplen;
00746 }
00747 else
00748 s += dplen + 9;
00749 for(; i < nd; i++)
00750 b = multadd(b, 10, *s++ - '0');
00751 return b;
00752 }
00753
00754 static int
00755 hi0bits
00756 #ifdef KR_headers
00757 (x) ULong x;
00758 #else
00759 (ULong x)
00760 #endif
00761 {
00762 int k = 0;
00763
00764 if (!(x & 0xffff0000)) {
00765 k = 16;
00766 x <<= 16;
00767 }
00768 if (!(x & 0xff000000)) {
00769 k += 8;
00770 x <<= 8;
00771 }
00772 if (!(x & 0xf0000000)) {
00773 k += 4;
00774 x <<= 4;
00775 }
00776 if (!(x & 0xc0000000)) {
00777 k += 2;
00778 x <<= 2;
00779 }
00780 if (!(x & 0x80000000)) {
00781 k++;
00782 if (!(x & 0x40000000))
00783 return 32;
00784 }
00785 return k;
00786 }
00787
00788 static int
00789 lo0bits
00790 #ifdef KR_headers
00791 (y) ULong *y;
00792 #else
00793 (ULong *y)
00794 #endif
00795 {
00796 int k;
00797 ULong x = *y;
00798
00799 if (x & 7) {
00800 if (x & 1)
00801 return 0;
00802 if (x & 2) {
00803 *y = x >> 1;
00804 return 1;
00805 }
00806 *y = x >> 2;
00807 return 2;
00808 }
00809 k = 0;
00810 if (!(x & 0xffff)) {
00811 k = 16;
00812 x >>= 16;
00813 }
00814 if (!(x & 0xff)) {
00815 k += 8;
00816 x >>= 8;
00817 }
00818 if (!(x & 0xf)) {
00819 k += 4;
00820 x >>= 4;
00821 }
00822 if (!(x & 0x3)) {
00823 k += 2;
00824 x >>= 2;
00825 }
00826 if (!(x & 1)) {
00827 k++;
00828 x >>= 1;
00829 if (!x)
00830 return 32;
00831 }
00832 *y = x;
00833 return k;
00834 }
00835
00836 static Bigint *
00837 i2b
00838 #ifdef KR_headers
00839 (i) int i;
00840 #else
00841 (int i)
00842 #endif
00843 {
00844 Bigint *b;
00845
00846 b = Balloc(1);
00847 b->x[0] = i;
00848 b->wds = 1;
00849 return b;
00850 }
00851
00852 static Bigint *
00853 mult
00854 #ifdef KR_headers
00855 (a, b) Bigint *a, *b;
00856 #else
00857 (Bigint *a, Bigint *b)
00858 #endif
00859 {
00860 Bigint *c;
00861 int k, wa, wb, wc;
00862 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
00863 ULong y;
00864 #ifdef ULLong
00865 ULLong carry, z;
00866 #else
00867 ULong carry, z;
00868 #ifdef Pack_32
00869 ULong z2;
00870 #endif
00871 #endif
00872
00873 if (a->wds < b->wds) {
00874 c = a;
00875 a = b;
00876 b = c;
00877 }
00878 k = a->k;
00879 wa = a->wds;
00880 wb = b->wds;
00881 wc = wa + wb;
00882 if (wc > a->maxwds)
00883 k++;
00884 c = Balloc(k);
00885 for(x = c->x, xa = x + wc; x < xa; x++)
00886 *x = 0;
00887 xa = a->x;
00888 xae = xa + wa;
00889 xb = b->x;
00890 xbe = xb + wb;
00891 xc0 = c->x;
00892 #ifdef ULLong
00893 for(; xb < xbe; xc0++) {
00894 if ((y = *xb++)) {
00895 x = xa;
00896 xc = xc0;
00897 carry = 0;
00898 do {
00899 z = *x++ * (ULLong)y + *xc + carry;
00900 carry = z >> 32;
00901 *xc++ = z & FFFFFFFF;
00902 }
00903 while(x < xae);
00904 *xc = carry;
00905 }
00906 }
00907 #else
00908 #ifdef Pack_32
00909 for(; xb < xbe; xb++, xc0++) {
00910 if (y = *xb & 0xffff) {
00911 x = xa;
00912 xc = xc0;
00913 carry = 0;
00914 do {
00915 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
00916 carry = z >> 16;
00917 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
00918 carry = z2 >> 16;
00919 Storeinc(xc, z2, z);
00920 }
00921 while(x < xae);
00922 *xc = carry;
00923 }
00924 if (y = *xb >> 16) {
00925 x = xa;
00926 xc = xc0;
00927 carry = 0;
00928 z2 = *xc;
00929 do {
00930 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
00931 carry = z >> 16;
00932 Storeinc(xc, z, z2);
00933 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
00934 carry = z2 >> 16;
00935 }
00936 while(x < xae);
00937 *xc = z2;
00938 }
00939 }
00940 #else
00941 for(; xb < xbe; xc0++) {
00942 if (y = *xb++) {
00943 x = xa;
00944 xc = xc0;
00945 carry = 0;
00946 do {
00947 z = *x++ * y + *xc + carry;
00948 carry = z >> 16;
00949 *xc++ = z & 0xffff;
00950 }
00951 while(x < xae);
00952 *xc = carry;
00953 }
00954 }
00955 #endif
00956 #endif
00957 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
00958 c->wds = wc;
00959 return c;
00960 }
00961
00962 static Bigint *p5s;
00963
00964 static Bigint *
00965 pow5mult
00966 #ifdef KR_headers
00967 (b, k) Bigint *b; int k;
00968 #else
00969 (Bigint *b, int k)
00970 #endif
00971 {
00972 Bigint *b1, *p5, *p51;
00973 int i;
00974 static int p05[3] = { 5, 25, 125 };
00975
00976 if ((i = k & 3))
00977 b = multadd(b, p05[i-1], 0);
00978
00979 if (!(k >>= 2))
00980 return b;
00981 if (!(p5 = p5s)) {
00982
00983 #ifdef MULTIPLE_THREADS
00984 ACQUIRE_DTOA_LOCK(1);
00985 if (!(p5 = p5s)) {
00986 p5 = p5s = i2b(625);
00987 p5->next = 0;
00988 }
00989 FREE_DTOA_LOCK(1);
00990 #else
00991 p5 = p5s = i2b(625);
00992 p5->next = 0;
00993 #endif
00994 }
00995 for(;;) {
00996 if (k & 1) {
00997 b1 = mult(b, p5);
00998 Bfree(b);
00999 b = b1;
01000 }
01001 if (!(k >>= 1))
01002 break;
01003 if (!(p51 = p5->next)) {
01004 #ifdef MULTIPLE_THREADS
01005 ACQUIRE_DTOA_LOCK(1);
01006 if (!(p51 = p5->next)) {
01007 p51 = p5->next = mult(p5,p5);
01008 p51->next = 0;
01009 }
01010 FREE_DTOA_LOCK(1);
01011 #else
01012 p51 = p5->next = mult(p5,p5);
01013 p51->next = 0;
01014 #endif
01015 }
01016 p5 = p51;
01017 }
01018 return b;
01019 }
01020
01021 static Bigint *
01022 lshift
01023 #ifdef KR_headers
01024 (b, k) Bigint *b; int k;
01025 #else
01026 (Bigint *b, int k)
01027 #endif
01028 {
01029 int i, k1, n, n1;
01030 Bigint *b1;
01031 ULong *x, *x1, *xe, z;
01032
01033 #ifdef Pack_32
01034 n = k >> 5;
01035 #else
01036 n = k >> 4;
01037 #endif
01038 k1 = b->k;
01039 n1 = n + b->wds + 1;
01040 for(i = b->maxwds; n1 > i; i <<= 1)
01041 k1++;
01042 b1 = Balloc(k1);
01043 x1 = b1->x;
01044 for(i = 0; i < n; i++)
01045 *x1++ = 0;
01046 x = b->x;
01047 xe = x + b->wds;
01048 #ifdef Pack_32
01049 if (k &= 0x1f) {
01050 k1 = 32 - k;
01051 z = 0;
01052 do {
01053 *x1++ = *x << k | z;
01054 z = *x++ >> k1;
01055 }
01056 while(x < xe);
01057 if ((*x1 = z))
01058 ++n1;
01059 }
01060 #else
01061 if (k &= 0xf) {
01062 k1 = 16 - k;
01063 z = 0;
01064 do {
01065 *x1++ = *x << k & 0xffff | z;
01066 z = *x++ >> k1;
01067 }
01068 while(x < xe);
01069 if (*x1 = z)
01070 ++n1;
01071 }
01072 #endif
01073 else do
01074 *x1++ = *x++;
01075 while(x < xe);
01076 b1->wds = n1 - 1;
01077 Bfree(b);
01078 return b1;
01079 }
01080
01081 static int
01082 cmp
01083 #ifdef KR_headers
01084 (a, b) Bigint *a, *b;
01085 #else
01086 (Bigint *a, Bigint *b)
01087 #endif
01088 {
01089 ULong *xa, *xa0, *xb, *xb0;
01090 int i, j;
01091
01092 i = a->wds;
01093 j = b->wds;
01094 #ifdef DEBUG
01095 if (i > 1 && !a->x[i-1])
01096 Bug("cmp called with a->x[a->wds-1] == 0");
01097 if (j > 1 && !b->x[j-1])
01098 Bug("cmp called with b->x[b->wds-1] == 0");
01099 #endif
01100 if (i -= j)
01101 return i;
01102 xa0 = a->x;
01103 xa = xa0 + j;
01104 xb0 = b->x;
01105 xb = xb0 + j;
01106 for(;;) {
01107 if (*--xa != *--xb)
01108 return *xa < *xb ? -1 : 1;
01109 if (xa <= xa0)
01110 break;
01111 }
01112 return 0;
01113 }
01114
01115 static Bigint *
01116 diff
01117 #ifdef KR_headers
01118 (a, b) Bigint *a, *b;
01119 #else
01120 (Bigint *a, Bigint *b)
01121 #endif
01122 {
01123 Bigint *c;
01124 int i, wa, wb;
01125 ULong *xa, *xae, *xb, *xbe, *xc;
01126 #ifdef ULLong
01127 ULLong borrow, y;
01128 #else
01129 ULong borrow, y;
01130 #ifdef Pack_32
01131 ULong z;
01132 #endif
01133 #endif
01134
01135 i = cmp(a,b);
01136 if (!i) {
01137 c = Balloc(0);
01138 c->wds = 1;
01139 c->x[0] = 0;
01140 return c;
01141 }
01142 if (i < 0) {
01143 c = a;
01144 a = b;
01145 b = c;
01146 i = 1;
01147 }
01148 else
01149 i = 0;
01150 c = Balloc(a->k);
01151 c->sign = i;
01152 wa = a->wds;
01153 xa = a->x;
01154 xae = xa + wa;
01155 wb = b->wds;
01156 xb = b->x;
01157 xbe = xb + wb;
01158 xc = c->x;
01159 borrow = 0;
01160 #ifdef ULLong
01161 do {
01162 y = (ULLong)*xa++ - *xb++ - borrow;
01163 borrow = y >> 32 & (ULong)1;
01164 *xc++ = y & FFFFFFFF;
01165 }
01166 while(xb < xbe);
01167 while(xa < xae) {
01168 y = *xa++ - borrow;
01169 borrow = y >> 32 & (ULong)1;
01170 *xc++ = y & FFFFFFFF;
01171 }
01172 #else
01173 #ifdef Pack_32
01174 do {
01175 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
01176 borrow = (y & 0x10000) >> 16;
01177 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
01178 borrow = (z & 0x10000) >> 16;
01179 Storeinc(xc, z, y);
01180 }
01181 while(xb < xbe);
01182 while(xa < xae) {
01183 y = (*xa & 0xffff) - borrow;
01184 borrow = (y & 0x10000) >> 16;
01185 z = (*xa++ >> 16) - borrow;
01186 borrow = (z & 0x10000) >> 16;
01187 Storeinc(xc, z, y);
01188 }
01189 #else
01190 do {
01191 y = *xa++ - *xb++ - borrow;
01192 borrow = (y & 0x10000) >> 16;
01193 *xc++ = y & 0xffff;
01194 }
01195 while(xb < xbe);
01196 while(xa < xae) {
01197 y = *xa++ - borrow;
01198 borrow = (y & 0x10000) >> 16;
01199 *xc++ = y & 0xffff;
01200 }
01201 #endif
01202 #endif
01203 while(!*--xc)
01204 wa--;
01205 c->wds = wa;
01206 return c;
01207 }
01208
01209 static double
01210 ulp
01211 #ifdef KR_headers
01212 (x) U *x;
01213 #else
01214 (U *x)
01215 #endif
01216 {
01217 Long L;
01218 U u;
01219
01220 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
01221 #ifndef Avoid_Underflow
01222 #ifndef Sudden_Underflow
01223 if (L > 0) {
01224 #endif
01225 #endif
01226 #ifdef IBM
01227 L |= Exp_msk1 >> 4;
01228 #endif
01229 word0(&u) = L;
01230 word1(&u) = 0;
01231 #ifndef Avoid_Underflow
01232 #ifndef Sudden_Underflow
01233 }
01234 else {
01235 L = -L >> Exp_shift;
01236 if (L < Exp_shift) {
01237 word0(&u) = 0x80000 >> L;
01238 word1(&u) = 0;
01239 }
01240 else {
01241 word0(&u) = 0;
01242 L -= Exp_shift;
01243 word1(&u) = L >= 31 ? 1 : 1 << 31 - L;
01244 }
01245 }
01246 #endif
01247 #endif
01248 return dval(&u);
01249 }
01250
01251 static double
01252 b2d
01253 #ifdef KR_headers
01254 (a, e) Bigint *a; int *e;
01255 #else
01256 (Bigint *a, int *e)
01257 #endif
01258 {
01259 ULong *xa, *xa0, w, y, z;
01260 int k;
01261 U d;
01262 #ifdef VAX
01263 ULong d0, d1;
01264 #else
01265 #define d0 word0(&d)
01266 #define d1 word1(&d)
01267 #endif
01268
01269 xa0 = a->x;
01270 xa = xa0 + a->wds;
01271 y = *--xa;
01272 #ifdef DEBUG
01273 if (!y) Bug("zero y in b2d");
01274 #endif
01275 k = hi0bits(y);
01276 *e = 32 - k;
01277 #ifdef Pack_32
01278 if (k < Ebits) {
01279 d0 = Exp_1 | y >> (Ebits - k);
01280 w = xa > xa0 ? *--xa : 0;
01281 d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
01282 goto ret_d;
01283 }
01284 z = xa > xa0 ? *--xa : 0;
01285 if (k -= Ebits) {
01286 d0 = Exp_1 | y << k | z >> (32 - k);
01287 y = xa > xa0 ? *--xa : 0;
01288 d1 = z << k | y >> (32 - k);
01289 }
01290 else {
01291 d0 = Exp_1 | y;
01292 d1 = z;
01293 }
01294 #else
01295 if (k < Ebits + 16) {
01296 z = xa > xa0 ? *--xa : 0;
01297 d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
01298 w = xa > xa0 ? *--xa : 0;
01299 y = xa > xa0 ? *--xa : 0;
01300 d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
01301 goto ret_d;
01302 }
01303 z = xa > xa0 ? *--xa : 0;
01304 w = xa > xa0 ? *--xa : 0;
01305 k -= Ebits + 16;
01306 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
01307 y = xa > xa0 ? *--xa : 0;
01308 d1 = w << k + 16 | y << k;
01309 #endif
01310 ret_d:
01311 #ifdef VAX
01312 word0(&d) = d0 >> 16 | d0 << 16;
01313 word1(&d) = d1 >> 16 | d1 << 16;
01314 #else
01315 #undef d0
01316 #undef d1
01317 #endif
01318 return dval(&d);
01319 }
01320
01321 static Bigint *
01322 d2b
01323 #ifdef KR_headers
01324 (d, e, bits) U *d; int *e, *bits;
01325 #else
01326 (U *d, int *e, int *bits)
01327 #endif
01328 {
01329 Bigint *b;
01330 int de, k;
01331 ULong *x, y, z;
01332 #ifndef Sudden_Underflow
01333 int i;
01334 #endif
01335 #ifdef VAX
01336 ULong d0, d1;
01337 d0 = word0(d) >> 16 | word0(d) << 16;
01338 d1 = word1(d) >> 16 | word1(d) << 16;
01339 #else
01340 #define d0 word0(d)
01341 #define d1 word1(d)
01342 #endif
01343
01344 #ifdef Pack_32
01345 b = Balloc(1);
01346 #else
01347 b = Balloc(2);
01348 #endif
01349 x = b->x;
01350
01351 z = d0 & Frac_mask;
01352 d0 &= 0x7fffffff;
01353 #ifdef Sudden_Underflow
01354 de = (int)(d0 >> Exp_shift);
01355 #ifndef IBM
01356 z |= Exp_msk11;
01357 #endif
01358 #else
01359 if ((de = (int)(d0 >> Exp_shift)))
01360 z |= Exp_msk1;
01361 #endif
01362 #ifdef Pack_32
01363 if ((y = d1)) {
01364 if ((k = lo0bits(&y))) {
01365 x[0] = y | z << (32 - k);
01366 z >>= k;
01367 }
01368 else
01369 x[0] = y;
01370 #ifndef Sudden_Underflow
01371 i =
01372 #endif
01373 b->wds = (x[1] = z) ? 2 : 1;
01374 }
01375 else {
01376 k = lo0bits(&z);
01377 x[0] = z;
01378 #ifndef Sudden_Underflow
01379 i =
01380 #endif
01381 b->wds = 1;
01382 k += 32;
01383 }
01384 #else
01385 if (y = d1) {
01386 if (k = lo0bits(&y))
01387 if (k >= 16) {
01388 x[0] = y | z << 32 - k & 0xffff;
01389 x[1] = z >> k - 16 & 0xffff;
01390 x[2] = z >> k;
01391 i = 2;
01392 }
01393 else {
01394 x[0] = y & 0xffff;
01395 x[1] = y >> 16 | z << 16 - k & 0xffff;
01396 x[2] = z >> k & 0xffff;
01397 x[3] = z >> k+16;
01398 i = 3;
01399 }
01400 else {
01401 x[0] = y & 0xffff;
01402 x[1] = y >> 16;
01403 x[2] = z & 0xffff;
01404 x[3] = z >> 16;
01405 i = 3;
01406 }
01407 }
01408 else {
01409 #ifdef DEBUG
01410 if (!z)
01411 Bug("Zero passed to d2b");
01412 #endif
01413 k = lo0bits(&z);
01414 if (k >= 16) {
01415 x[0] = z;
01416 i = 0;
01417 }
01418 else {
01419 x[0] = z & 0xffff;
01420 x[1] = z >> 16;
01421 i = 1;
01422 }
01423 k += 32;
01424 }
01425 while(!x[i])
01426 --i;
01427 b->wds = i + 1;
01428 #endif
01429 #ifndef Sudden_Underflow
01430 if (de) {
01431 #endif
01432 #ifdef IBM
01433 *e = (de - Bias - (P-1) << 2) + k;
01434 *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
01435 #else
01436 *e = de - Bias - (P-1) + k;
01437 *bits = P - k;
01438 #endif
01439 #ifndef Sudden_Underflow
01440 }
01441 else {
01442 *e = de - Bias - (P-1) + 1 + k;
01443 #ifdef Pack_32
01444 *bits = 32*i - hi0bits(x[i-1]);
01445 #else
01446 *bits = (i+2)*16 - hi0bits(x[i]);
01447 #endif
01448 }
01449 #endif
01450 return b;
01451 }
01452 #undef d0
01453 #undef d1
01454
01455 static double
01456 ratio
01457 #ifdef KR_headers
01458 (a, b) Bigint *a, *b;
01459 #else
01460 (Bigint *a, Bigint *b)
01461 #endif
01462 {
01463 U da, db;
01464 int k, ka, kb;
01465
01466 dval(&da) = b2d(a, &ka);
01467 dval(&db) = b2d(b, &kb);
01468 #ifdef Pack_32
01469 k = ka - kb + 32*(a->wds - b->wds);
01470 #else
01471 k = ka - kb + 16*(a->wds - b->wds);
01472 #endif
01473 #ifdef IBM
01474 if (k > 0) {
01475 word0(&da) += (k >> 2)*Exp_msk1;
01476 if (k &= 3)
01477 dval(&da) *= 1 << k;
01478 }
01479 else {
01480 k = -k;
01481 word0(&db) += (k >> 2)*Exp_msk1;
01482 if (k &= 3)
01483 dval(&db) *= 1 << k;
01484 }
01485 #else
01486 if (k > 0)
01487 word0(&da) += k*Exp_msk1;
01488 else {
01489 k = -k;
01490 word0(&db) += k*Exp_msk1;
01491 }
01492 #endif
01493 return dval(&da) / dval(&db);
01494 }
01495
01496 static CONST double
01497 tens[] = {
01498 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
01499 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
01500 1e20, 1e21, 1e22
01501 #ifdef VAX
01502 , 1e23, 1e24
01503 #endif
01504 };
01505
01506 static CONST double
01507 #ifdef IEEE_Arith
01508 bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
01509 static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
01510 #ifdef Avoid_Underflow
01511 9007199254740992.*9007199254740992.e-256
01512
01513 #else
01514 1e-256
01515 #endif
01516 };
01517
01518
01519 #define Scale_Bit 0x10
01520 #define n_bigtens 5
01521 #else
01522 #ifdef IBM
01523 bigtens[] = { 1e16, 1e32, 1e64 };
01524 static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
01525 #define n_bigtens 3
01526 #else
01527 bigtens[] = { 1e16, 1e32 };
01528 static CONST double tinytens[] = { 1e-16, 1e-32 };
01529 #define n_bigtens 2
01530 #endif
01531 #endif
01532
01533 #undef Need_Hexdig
01534 #ifdef INFNAN_CHECK
01535 #ifndef No_Hex_NaN
01536 #define Need_Hexdig
01537 #endif
01538 #endif
01539
01540 #ifndef Need_Hexdig
01541 #ifndef NO_HEX_FP
01542 #define Need_Hexdig
01543 #endif
01544 #endif
01545
01546 #ifdef Need_Hexdig
01547 #if 0
01548 static unsigned char hexdig[256];
01549
01550 static void
01551 htinit(unsigned char *h, unsigned char *s, int inc)
01552 {
01553 int i, j;
01554 for(i = 0; (j = s[i]) !=0; i++)
01555 h[j] = i + inc;
01556 }
01557
01558 static void
01559 hexdig_init(void)
01560
01561 {
01562 #define USC (unsigned char *)
01563 htinit(hexdig, USC "0123456789", 0x10);
01564 htinit(hexdig, USC "abcdef", 0x10 + 10);
01565 htinit(hexdig, USC "ABCDEF", 0x10 + 10);
01566 }
01567 #else
01568 static unsigned char hexdig[256] = {
01569 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01570 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01571 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01572 16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,
01573 0,26,27,28,29,30,31,0,0,0,0,0,0,0,0,0,
01574 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01575 0,26,27,28,29,30,31,0,0,0,0,0,0,0,0,0,
01576 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01577 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01578 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01579 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01580 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01581 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01582 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01583 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
01584 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
01585 };
01586 #endif
01587 #endif
01588
01589 #ifdef INFNAN_CHECK
01590
01591 #ifndef NAN_WORD0
01592 #define NAN_WORD0 0x7ff80000
01593 #endif
01594
01595 #ifndef NAN_WORD1
01596 #define NAN_WORD1 0
01597 #endif
01598
01599 static int
01600 match
01601 #ifdef KR_headers
01602 (sp, t) char **sp, *t;
01603 #else
01604 (const char **sp, const char *t)
01605 #endif
01606 {
01607 int c, d;
01608 CONST char *s = *sp;
01609
01610 while((d = *t++)) {
01611 if ((c = *++s) >= 'A' && c <= 'Z')
01612 c += 'a' - 'A';
01613 if (c != d)
01614 return 0;
01615 }
01616 *sp = s + 1;
01617 return 1;
01618 }
01619
01620 #ifndef No_Hex_NaN
01621 static void
01622 hexnan
01623 #ifdef KR_headers
01624 (rvp, sp) U *rvp; CONST char **sp;
01625 #else
01626 (U *rvp, const char **sp)
01627 #endif
01628 {
01629 ULong c, x[2];
01630 CONST char *s;
01631 int c1, havedig, udx0, xshift;
01632
01633
01634 x[0] = x[1] = 0;
01635 havedig = xshift = 0;
01636 udx0 = 1;
01637 s = *sp;
01638
01639 while((c = *(CONST unsigned char*)(s+1)) && c <= ' ')
01640 ++s;
01641 if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X'))
01642 s += 2;
01643 while((c = *(CONST unsigned char*)++s)) {
01644 if ((c1 = hexdig[c]))
01645 c = c1 & 0xf;
01646 else if (c <= ' ') {
01647 if (udx0 && havedig) {
01648 udx0 = 0;
01649 xshift = 1;
01650 }
01651 continue;
01652 }
01653 #ifdef GDTOA_NON_PEDANTIC_NANCHECK
01654 else if ( c == ')' && havedig) {
01655 *sp = s + 1;
01656 break;
01657 }
01658 else
01659 return;
01660 #else
01661 else {
01662 do {
01663 if ( c == ')') {
01664 *sp = s + 1;
01665 break;
01666 }
01667 } while((c = *++s));
01668 break;
01669 }
01670 #endif
01671 havedig = 1;
01672 if (xshift) {
01673 xshift = 0;
01674 x[0] = x[1];
01675 x[1] = 0;
01676 }
01677 if (udx0)
01678 x[0] = (x[0] << 4) | (x[1] >> 28);
01679 x[1] = (x[1] << 4) | c;
01680 }
01681 if ((x[0] &= 0xfffff) || x[1]) {
01682 word0(rvp) = Exp_mask | x[0];
01683 word1(rvp) = x[1];
01684 }
01685 }
01686 #endif
01687 #endif
01688
01689 #ifdef Pack_32
01690 #define ULbits 32
01691 #define kshift 5
01692 #define kmask 31
01693 #else
01694 #define ULbits 16
01695 #define kshift 4
01696 #define kmask 15
01697 #endif
01698
01699 #if !defined(NO_HEX_FP) || defined(Honor_FLT_ROUNDS)
01700 static Bigint *
01701 #ifdef KR_headers
01702 increment(b) Bigint *b;
01703 #else
01704 increment(Bigint *b)
01705 #endif
01706 {
01707 ULong *x, *xe;
01708 Bigint *b1;
01709
01710 x = b->x;
01711 xe = x + b->wds;
01712 do {
01713 if (*x < (ULong)0xffffffffL) {
01714 ++*x;
01715 return b;
01716 }
01717 *x++ = 0;
01718 } while(x < xe);
01719 {
01720 if (b->wds >= b->maxwds) {
01721 b1 = Balloc(b->k+1);
01722 Bcopy(b1,b);
01723 Bfree(b);
01724 b = b1;
01725 }
01726 b->x[b->wds++] = 1;
01727 }
01728 return b;
01729 }
01730
01731 #endif
01732
01733 #ifndef NO_HEX_FP
01734
01735 static void
01736 #ifdef KR_headers
01737 rshift(b, k) Bigint *b; int k;
01738 #else
01739 rshift(Bigint *b, int k)
01740 #endif
01741 {
01742 ULong *x, *x1, *xe, y;
01743 int n;
01744
01745 x = x1 = b->x;
01746 n = k >> kshift;
01747 if (n < b->wds) {
01748 xe = x + b->wds;
01749 x += n;
01750 if (k &= kmask) {
01751 n = 32 - k;
01752 y = *x++ >> k;
01753 while(x < xe) {
01754 *x1++ = (y | (*x << n)) & 0xffffffff;
01755 y = *x++ >> k;
01756 }
01757 if ((*x1 = y) !=0)
01758 x1++;
01759 }
01760 else
01761 while(x < xe)
01762 *x1++ = *x++;
01763 }
01764 if ((b->wds = x1 - b->x) == 0)
01765 b->x[0] = 0;
01766 }
01767
01768 static ULong
01769 #ifdef KR_headers
01770 any_on(b, k) Bigint *b; int k;
01771 #else
01772 any_on(Bigint *b, int k)
01773 #endif
01774 {
01775 int n, nwds;
01776 ULong *x, *x0, x1, x2;
01777
01778 x = b->x;
01779 nwds = b->wds;
01780 n = k >> kshift;
01781 if (n > nwds)
01782 n = nwds;
01783 else if (n < nwds && (k &= kmask)) {
01784 x1 = x2 = x[n];
01785 x1 >>= k;
01786 x1 <<= k;
01787 if (x1 != x2)
01788 return 1;
01789 }
01790 x0 = x;
01791 x += n;
01792 while(x > x0)
01793 if (*--x)
01794 return 1;
01795 return 0;
01796 }
01797
01798 enum {
01799 Round_zero = 0,
01800 Round_near = 1,
01801 Round_up = 2,
01802 Round_down = 3
01803 };
01804
01805 void
01806 #ifdef KR_headers
01807 os_gethex(sp, rvp, rounding, sign)
01808 CONST char **sp; U *rvp; int rounding, sign;
01809 #else
01810 os_gethex( CONST char **sp, U *rvp, int rounding, int sign)
01811 #endif
01812 {
01813 Bigint *b;
01814 CONST unsigned char *decpt, *s0, *s, *s1;
01815 Long e, e1;
01816 ULong L, lostbits, *x;
01817 int big, denorm, esign, havedig, k, n, nbits, up, zret;
01818 #ifdef IBM
01819 int j;
01820 #endif
01821 enum {
01822 #ifdef IEEE_Arith
01823 emax = 0x7fe - Bias - P + 1,
01824 emin = Emin - P + 1
01825 #else
01826 emin = Emin - P,
01827 #ifdef VAX
01828 emax = 0x7ff - Bias - P + 1
01829 #endif
01830 #ifdef IBM
01831 emax = 0x7f - Bias - P
01832 #endif
01833 #endif
01834 };
01835 #ifdef USE_LOCALE
01836 int i;
01837 #ifdef NO_LOCALE_CACHE
01838 const unsigned char *decimalpoint = (unsigned char*)
01839 localeconv()->decimal_point;
01840 #else
01841 const unsigned char *decimalpoint;
01842 static unsigned char *decimalpoint_cache;
01843 if (!(s0 = decimalpoint_cache)) {
01844 s0 = (unsigned char*)localeconv()->decimal_point;
01845 if ((decimalpoint_cache = (unsigned char*)
01846 MALLOC(strlen((CONST char*)s0) + 1))) {
01847 strcpy((char*)decimalpoint_cache, (CONST char*)s0);
01848 s0 = decimalpoint_cache;
01849 }
01850 }
01851 decimalpoint = s0;
01852 #endif
01853 #endif
01854
01855
01856 havedig = 0;
01857 s0 = *(CONST unsigned char **)sp + 2;
01858 while(s0[havedig] == '0')
01859 havedig++;
01860 s0 += havedig;
01861 s = s0;
01862 decpt = 0;
01863 zret = 0;
01864 e = 0;
01865 if (hexdig[*s])
01866 havedig++;
01867 else {
01868 zret = 1;
01869 #ifdef USE_LOCALE
01870 for(i = 0; decimalpoint[i]; ++i) {
01871 if (s[i] != decimalpoint[i])
01872 goto pcheck;
01873 }
01874 decpt = s += i;
01875 #else
01876 if (*s != '.')
01877 goto pcheck;
01878 decpt = ++s;
01879 #endif
01880 if (!hexdig[*s])
01881 goto pcheck;
01882 while(*s == '0')
01883 s++;
01884 if (hexdig[*s])
01885 zret = 0;
01886 havedig = 1;
01887 s0 = s;
01888 }
01889 while(hexdig[*s])
01890 s++;
01891 #ifdef USE_LOCALE
01892 if (*s == *decimalpoint && !decpt) {
01893 for(i = 1; decimalpoint[i]; ++i) {
01894 if (s[i] != decimalpoint[i])
01895 goto pcheck;
01896 }
01897 decpt = s += i;
01898 #else
01899 if (*s == '.' && !decpt) {
01900 decpt = ++s;
01901 #endif
01902 while(hexdig[*s])
01903 s++;
01904 }
01905 if (decpt)
01906 e = -(((Long)(s-decpt)) << 2);
01907 pcheck:
01908 s1 = s;
01909 big = esign = 0;
01910 switch(*s) {
01911 case 'p':
01912 case 'P':
01913 switch(*++s) {
01914 case '-':
01915 esign = 1;
01916
01917 case '+':
01918 s++;
01919 }
01920 if ((n = hexdig[*s]) == 0 || n > 0x19) {
01921 s = s1;
01922 break;
01923 }
01924 e1 = n - 0x10;
01925 while((n = hexdig[*++s]) !=0 && n <= 0x19) {
01926 if (e1 & 0xf8000000)
01927 big = 1;
01928 e1 = 10*e1 + n - 0x10;
01929 }
01930 if (esign)
01931 e1 = -e1;
01932 e += e1;
01933 }
01934 *sp = (char*)s;
01935 if (!havedig)
01936 *sp = (char*)s0 - 1;
01937 if (zret)
01938 goto retz1;
01939 if (big) {
01940 if (esign) {
01941 #ifdef IEEE_Arith
01942 switch(rounding) {
01943 case Round_up:
01944 if (sign)
01945 break;
01946 goto ret_tiny;
01947 case Round_down:
01948 if (!sign)
01949 break;
01950 goto ret_tiny;
01951 }
01952 #endif
01953 goto retz;
01954 #ifdef IEEE_Arith
01955 ret_tinyf:
01956 Bfree(b);
01957 ret_tiny:
01958 #ifndef NO_ERRNO
01959 errno = ERANGE;
01960 #endif
01961 word0(rvp) = 0;
01962 word1(rvp) = 1;
01963 return;
01964 #endif
01965 }
01966 switch(rounding) {
01967 case Round_near:
01968 goto ovfl1;
01969 case Round_up:
01970 if (!sign)
01971 goto ovfl1;
01972 goto ret_big;
01973 case Round_down:
01974 if (sign)
01975 goto ovfl1;
01976 goto ret_big;
01977 }
01978 ret_big:
01979 word0(rvp) = Big0;
01980 word1(rvp) = Big1;
01981 return;
01982 }
01983 n = s1 - s0 - 1;
01984 for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1)
01985 k++;
01986 b = Balloc(k);
01987 x = b->x;
01988 n = 0;
01989 L = 0;
01990 #ifdef USE_LOCALE
01991 for(i = 0; decimalpoint[i+1]; ++i);
01992 #endif
01993 while(s1 > s0) {
01994 #ifdef USE_LOCALE
01995 if (*--s1 == decimalpoint[i]) {
01996 s1 -= i;
01997 continue;
01998 }
01999 #else
02000 if (*--s1 == '.')
02001 continue;
02002 #endif
02003 if (n == ULbits) {
02004 *x++ = L;
02005 L = 0;
02006 n = 0;
02007 }
02008 L |= (hexdig[*s1] & 0x0f) << n;
02009 n += 4;
02010 }
02011 *x++ = L;
02012 b->wds = n = x - b->x;
02013 n = ULbits*n - hi0bits(L);
02014 nbits = Nbits;
02015 lostbits = 0;
02016 x = b->x;
02017 if (n > nbits) {
02018 n -= nbits;
02019 if (any_on(b,n)) {
02020 lostbits = 1;
02021 k = n - 1;
02022 if (x[k>>kshift] & 1 << (k & kmask)) {
02023 lostbits = 2;
02024 if (k > 0 && any_on(b,k))
02025 lostbits = 3;
02026 }
02027 }
02028 rshift(b, n);
02029 e += n;
02030 }
02031 else if (n < nbits) {
02032 n = nbits - n;
02033 b = lshift(b, n);
02034 e -= n;
02035 x = b->x;
02036 }
02037 if (e > Emax) {
02038 ovfl:
02039 Bfree(b);
02040 ovfl1:
02041 #ifndef NO_ERRNO
02042 errno = ERANGE;
02043 #endif
02044 word0(rvp) = Exp_mask;
02045 word1(rvp) = 0;
02046 return;
02047 }
02048 denorm = 0;
02049 if (e < emin) {
02050 denorm = 1;
02051 n = emin - e;
02052 if (n >= nbits) {
02053 #ifdef IEEE_Arith
02054 switch (rounding) {
02055 case Round_near:
02056 if (n == nbits && (n < 2 || any_on(b,n-1)))
02057 goto ret_tinyf;
02058 break;
02059 case Round_up:
02060 if (!sign)
02061 goto ret_tinyf;
02062 break;
02063 case Round_down:
02064 if (sign)
02065 goto ret_tinyf;
02066 }
02067 #endif
02068 Bfree(b);
02069 retz:
02070 #ifndef NO_ERRNO
02071 errno = ERANGE;
02072 #endif
02073 retz1:
02074 rvp->d = 0.;
02075 return;
02076 }
02077 k = n - 1;
02078 if (lostbits)
02079 lostbits = 1;
02080 else if (k > 0)
02081 lostbits = any_on(b,k);
02082 if (x[k>>kshift] & 1 << (k & kmask))
02083 lostbits |= 2;
02084 nbits -= n;
02085 rshift(b,n);
02086 e = emin;
02087 }
02088 if (lostbits) {
02089 up = 0;
02090 switch(rounding) {
02091 case Round_zero:
02092 break;
02093 case Round_near:
02094 if (lostbits & 2
02095 && (lostbits & 1) | (x[0] & 1))
02096 up = 1;
02097 break;
02098 case Round_up:
02099 up = 1 - sign;
02100 break;
02101 case Round_down:
02102 up = sign;
02103 }
02104 if (up) {
02105 k = b->wds;
02106 b = increment(b);
02107 x = b->x;
02108 if (denorm) {
02109 #if 0
02110 if (nbits == Nbits - 1
02111 && x[nbits >> kshift] & 1 << (nbits & kmask))
02112 denorm = 0;
02113 #endif
02114 }
02115 else if (b->wds > k
02116 || ((n = nbits & kmask) !=0
02117 && hi0bits(x[k-1]) < 32-n)) {
02118 rshift(b,1);
02119 if (++e > Emax)
02120 goto ovfl;
02121 }
02122 }
02123 }
02124 #ifdef IEEE_Arith
02125 if (denorm)
02126 word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0;
02127 else
02128 word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20);
02129 word1(rvp) = b->x[0];
02130 #endif
02131 #ifdef IBM
02132 if ((j = e & 3)) {
02133 k = b->x[0] & ((1 << j) - 1);
02134 rshift(b,j);
02135 if (k) {
02136 switch(rounding) {
02137 case Round_up:
02138 if (!sign)
02139 increment(b);
02140 break;
02141 case Round_down:
02142 if (sign)
02143 increment(b);
02144 break;
02145 case Round_near:
02146 j = 1 << (j-1);
02147 if (k & j && ((k & (j-1)) | lostbits))
02148 increment(b);
02149 }
02150 }
02151 }
02152 e >>= 2;
02153 word0(rvp) = b->x[1] | ((e + 65 + 13) << 24);
02154 word1(rvp) = b->x[0];
02155 #endif
02156 #ifdef VAX
02157
02158
02159
02160 word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16);
02161 word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16);
02162 #endif
02163 Bfree(b);
02164 }
02165 #endif
02167 static int
02168 #ifdef KR_headers
02169 dshift(b, p2) Bigint *b; int p2;
02170 #else
02171 dshift(Bigint *b, int p2)
02172 #endif
02173 {
02174 int rv = hi0bits(b->x[b->wds-1]) - 4;
02175 if (p2 > 0)
02176 rv -= p2;
02177 return rv & kmask;
02178 }
02179
02180 static int
02181 quorem
02182 #ifdef KR_headers
02183 (b, S) Bigint *b, *S;
02184 #else
02185 (Bigint *b, Bigint *S)
02186 #endif
02187 {
02188 int n;
02189 ULong *bx, *bxe, q, *sx, *sxe;
02190 #ifdef ULLong
02191 ULLong borrow, carry, y, ys;
02192 #else
02193 ULong borrow, carry, y, ys;
02194 #ifdef Pack_32
02195 ULong si, z, zs;
02196 #endif
02197 #endif
02198
02199 n = S->wds;
02200 #ifdef DEBUG
02201 if (b->wds > n)
02202 Bug("oversize b in quorem");
02203 #endif
02204 if (b->wds < n)
02205 return 0;
02206 sx = S->x;
02207 sxe = sx + --n;
02208 bx = b->x;
02209 bxe = bx + n;
02210 q = *bxe / (*sxe + 1);
02211 #ifdef DEBUG
02212 #ifdef NO_STRTOD_BIGCOMP
02213 if (q > 9)
02214 #else
02215
02216
02217 if (q > 15)
02218 #endif
02219 Bug("oversized quotient in quorem");
02220 #endif
02221 if (q) {
02222 borrow = 0;
02223 carry = 0;
02224 do {
02225 #ifdef ULLong
02226 ys = *sx++ * (ULLong)q + carry;
02227 carry = ys >> 32;
02228 y = *bx - (ys & FFFFFFFF) - borrow;
02229 borrow = y >> 32 & (ULong)1;
02230 *bx++ = y & FFFFFFFF;
02231 #else
02232 #ifdef Pack_32
02233 si = *sx++;
02234 ys = (si & 0xffff) * q + carry;
02235 zs = (si >> 16) * q + (ys >> 16);
02236 carry = zs >> 16;
02237 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
02238 borrow = (y & 0x10000) >> 16;
02239 z = (*bx >> 16) - (zs & 0xffff) - borrow;
02240 borrow = (z & 0x10000) >> 16;
02241 Storeinc(bx, z, y);
02242 #else
02243 ys = *sx++ * q + carry;
02244 carry = ys >> 16;
02245 y = *bx - (ys & 0xffff) - borrow;
02246 borrow = (y & 0x10000) >> 16;
02247 *bx++ = y & 0xffff;
02248 #endif
02249 #endif
02250 }
02251 while(sx <= sxe);
02252 if (!*bxe) {
02253 bx = b->x;
02254 while(--bxe > bx && !*bxe)
02255 --n;
02256 b->wds = n;
02257 }
02258 }
02259 if (cmp(b, S) >= 0) {
02260 q++;
02261 borrow = 0;
02262 carry = 0;
02263 bx = b->x;
02264 sx = S->x;
02265 do {
02266 #ifdef ULLong
02267 ys = *sx++ + carry;
02268 carry = ys >> 32;
02269 y = *bx - (ys & FFFFFFFF) - borrow;
02270 borrow = y >> 32 & (ULong)1;
02271 *bx++ = y & FFFFFFFF;
02272 #else
02273 #ifdef Pack_32
02274 si = *sx++;
02275 ys = (si & 0xffff) + carry;
02276 zs = (si >> 16) + (ys >> 16);
02277 carry = zs >> 16;
02278 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
02279 borrow = (y & 0x10000) >> 16;
02280 z = (*bx >> 16) - (zs & 0xffff) - borrow;
02281 borrow = (z & 0x10000) >> 16;
02282 Storeinc(bx, z, y);
02283 #else
02284 ys = *sx++ + carry;
02285 carry = ys >> 16;
02286 y = *bx - (ys & 0xffff) - borrow;
02287 borrow = (y & 0x10000) >> 16;
02288 *bx++ = y & 0xffff;
02289 #endif
02290 #endif
02291 }
02292 while(sx <= sxe);
02293 bx = b->x;
02294 bxe = bx + n;
02295 if (!*bxe) {
02296 while(--bxe > bx && !*bxe)
02297 --n;
02298 b->wds = n;
02299 }
02300 }
02301 return q;
02302 }
02303
02304 #if defined(Avoid_Underflow) || !defined(NO_STRTOD_BIGCOMP)
02305 static double
02306 sulp
02307 #ifdef KR_headers
02308 (x, bc) U *x; BCinfo *bc;
02309 #else
02310 (U *x, BCinfo *bc)
02311 #endif
02312 {
02313 U u;
02314 double rv;
02315 int i;
02316
02317 rv = ulp(x);
02318 if (!bc->scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0)
02319 return rv;
02320 word0(&u) = Exp_1 + (i << Exp_shift);
02321 word1(&u) = 0;
02322 return rv * u.d;
02323 }
02324 #endif
02325
02326 #ifndef NO_STRTOD_BIGCOMP
02327 static void
02328 bigcomp
02329 #ifdef KR_headers
02330 (rv, s0, bc)
02331 U *rv; CONST char *s0; BCinfo *bc;
02332 #else
02333 (U *rv, const char *s0, BCinfo *bc)
02334 #endif
02335 {
02336 Bigint *b, *d;
02337 int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase;
02338
02339 dsign = bc->dsign;
02340 nd = bc->nd;
02341 nd0 = bc->nd0;
02342 p5 = nd + bc->e0 - 1;
02343 speccase = 0;
02344 #ifndef Sudden_Underflow
02345 if (rv->d == 0.) {
02346
02347 b = i2b(1);
02348 p2 = Emin - P + 1;
02349 bbits = 1;
02350 #ifdef Avoid_Underflow
02351 word0(rv) = (P+2) << Exp_shift;
02352 #else
02353 word1(rv) = 1;
02354 #endif
02355 i = 0;
02356 #ifdef Honor_FLT_ROUNDS
02357 if (bc->rounding == 1)
02358 #endif
02359 {
02360 speccase = 1;
02361 --p2;
02362 dsign = 0;
02363 goto have_i;
02364 }
02365 }
02366 else
02367 #endif
02368 b = d2b(rv, &p2, &bbits);
02369 #ifdef Avoid_Underflow
02370 p2 -= bc->scale;
02371 #endif
02372
02373
02374 i = P - bbits;
02375 if (i > (j = P - Emin - 1 + p2)) {
02376 #ifdef Sudden_Underflow
02377 Bfree(b);
02378 b = i2b(1);
02379 p2 = Emin;
02380 i = P - 1;
02381 #ifdef Avoid_Underflow
02382 word0(rv) = (1 + bc->scale) << Exp_shift;
02383 #else
02384 word0(rv) = Exp_msk1;
02385 #endif
02386 word1(rv) = 0;
02387 #else
02388 i = j;
02389 #endif
02390 }
02391 #ifdef Honor_FLT_ROUNDS
02392 if (bc->rounding != 1) {
02393 if (i > 0)
02394 b = lshift(b, i);
02395 if (dsign)
02396 b = increment(b);
02397 }
02398 else
02399 #endif
02400 {
02401 b = lshift(b, ++i);
02402 b->x[0] |= 1;
02403 }
02404 #ifndef Sudden_Underflow
02405 have_i:
02406 #endif
02407 p2 -= p5 + i;
02408 d = i2b(1);
02409
02410
02411
02412 if (p5 > 0)
02413 d = pow5mult(d, p5);
02414 else if (p5 < 0)
02415 b = pow5mult(b, -p5);
02416 if (p2 > 0) {
02417 b2 = p2;
02418 d2 = 0;
02419 }
02420 else {
02421 b2 = 0;
02422 d2 = -p2;
02423 }
02424 i = dshift(d, d2);
02425 if ((b2 += i) > 0)
02426 b = lshift(b, b2);
02427 if ((d2 += i) > 0)
02428 d = lshift(d, d2);
02429
02430
02431
02432
02433 if (!(dig = quorem(b,d))) {
02434 b = multadd(b, 10, 0);
02435 dig = quorem(b,d);
02436 }
02437
02438
02439
02440 for(i = 0; i < nd0; ) {
02441 if ((dd = s0[i++] - '0' - dig))
02442 goto ret;
02443 if (!b->x[0] && b->wds == 1) {
02444 if (i < nd)
02445 dd = 1;
02446 goto ret;
02447 }
02448 b = multadd(b, 10, 0);
02449 dig = quorem(b,d);
02450 }
02451 for(j = bc->dp1; i++ < nd;) {
02452 if ((dd = s0[j++] - '0' - dig))
02453 goto ret;
02454 if (!b->x[0] && b->wds == 1) {
02455 if (i < nd)
02456 dd = 1;
02457 goto ret;
02458 }
02459 b = multadd(b, 10, 0);
02460 dig = quorem(b,d);
02461 }
02462 if (dig > 0 || b->x[0] || b->wds > 1)
02463 dd = -1;
02464 ret:
02465 Bfree(b);
02466 Bfree(d);
02467 #ifdef Honor_FLT_ROUNDS
02468 if (bc->rounding != 1) {
02469 if (dd < 0) {
02470 if (bc->rounding == 0) {
02471 if (!dsign)
02472 goto retlow1;
02473 }
02474 else if (dsign)
02475 goto rethi1;
02476 }
02477 else if (dd > 0) {
02478 if (bc->rounding == 0) {
02479 if (dsign)
02480 goto rethi1;
02481 goto ret1;
02482 }
02483 if (!dsign)
02484 goto rethi1;
02485 dval(rv) += 2.*sulp(rv,bc);
02486 }
02487 else {
02488 bc->inexact = 0;
02489 if (dsign)
02490 goto rethi1;
02491 }
02492 }
02493 else
02494 #endif
02495 if (speccase) {
02496 if (dd <= 0)
02497 rv->d = 0.;
02498 }
02499 else if (dd < 0) {
02500 if (!dsign)
02501 retlow1:
02502 dval(rv) -= sulp(rv,bc);
02503 }
02504 else if (dd > 0) {
02505 if (dsign) {
02506 rethi1:
02507 dval(rv) += sulp(rv,bc);
02508 }
02509 }
02510 else {
02511
02512 if ((j = ((word0(rv) & Exp_mask) >> Exp_shift) - bc->scale) <= 0) {
02513 i = 1 - j;
02514 if (i <= 31) {
02515 if (word1(rv) & (0x1 << i))
02516 goto odd;
02517 }
02518 else if (word0(rv) & (0x1 << (i-32)))
02519 goto odd;
02520 }
02521 else if (word1(rv) & 1) {
02522 odd:
02523 if (dsign)
02524 goto rethi1;
02525 goto retlow1;
02526 }
02527 }
02528
02529 #ifdef Honor_FLT_ROUNDS
02530 ret1:
02531 #endif
02532 return;
02533 }
02534 #endif
02535
02536 double
02537 os_strtod
02538 #ifdef KR_headers
02539 (s00, se) CONST char *s00; char **se;
02540 #else
02541 (const char *s00, char **se)
02542 #endif
02543 {
02544 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1;
02545 int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign;
02546 CONST char *s, *s0, *s1;
02547 double aadj, aadj1;
02548 Long L;
02549 U aadj2, adj, rv, rv0;
02550 ULong y, z;
02551 BCinfo bc;
02552 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
02553 #ifdef Avoid_Underflow
02554 ULong Lsb, Lsb1;
02555 #endif
02556 #ifdef SET_INEXACT
02557 int oldinexact;
02558 #endif
02559 #ifndef NO_STRTOD_BIGCOMP
02560 int req_bigcomp = 0;
02561 #endif
02562 #ifdef Honor_FLT_ROUNDS
02563 #ifdef Trust_FLT_ROUNDS
02564 bc.rounding = Flt_Rounds;
02565 #else
02566 bc.rounding = 1;
02567 switch(fegetround()) {
02568 case FE_TOWARDZERO: bc.rounding = 0; break;
02569 case FE_UPWARD: bc.rounding = 2; break;
02570 case FE_DOWNWARD: bc.rounding = 3;
02571 }
02572 #endif
02573 #endif
02574 #ifdef USE_LOCALE
02575 CONST char *s2;
02576 #endif
02577
02578 sign = nz0 = nz1 = nz = bc.dplen = bc.uflchk = 0;
02579 dval(&rv) = 0.;
02580 for(s = s00;;s++) switch(*s) {
02581 case '-':
02582 sign = 1;
02583
02584 case '+':
02585 if (*++s)
02586 goto break2;
02587
02588 case 0:
02589 goto ret0;
02590 case '\t':
02591 case '\n':
02592 case '\v':
02593 case '\f':
02594 case '\r':
02595 case ' ':
02596 continue;
02597 default:
02598 goto break2;
02599 }
02600 break2:
02601 if (*s == '0') {
02602 #ifndef NO_HEX_FP
02603 switch(s[1]) {
02604 case 'x':
02605 case 'X':
02606 #ifdef Honor_FLT_ROUNDS
02607 os_gethex(&s, &rv, bc.rounding, sign);
02608 #else
02609 os_gethex(&s, &rv, 1, sign);
02610 #endif
02611 goto ret;
02612 }
02613 #endif
02614 nz0 = 1;
02615 while(*++s == '0') ;
02616 if (!*s)
02617 goto ret;
02618 }
02619 s0 = s;
02620 y = z = 0;
02621 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
02622 if (nd < 9)
02623 y = 10*y + c - '0';
02624 else if (nd < 16)
02625 z = 10*z + c - '0';
02626 nd0 = nd;
02627 bc.dp0 = bc.dp1 = s - s0;
02628 for(s1 = s; s1 > s0 && *--s1 == '0'; )
02629 ++nz1;
02630 #ifdef USE_LOCALE
02631 s1 = localeconv()->decimal_point;
02632 if (c == *s1) {
02633 c = '.';
02634 if (*++s1) {
02635 s2 = s;
02636 for(;;) {
02637 if (*++s2 != *s1) {
02638 c = 0;
02639 break;
02640 }
02641 if (!*++s1) {
02642 s = s2;
02643 break;
02644 }
02645 }
02646 }
02647 }
02648 #endif
02649 if (c == '.') {
02650 c = *++s;
02651 bc.dp1 = s - s0;
02652 bc.dplen = bc.dp1 - bc.dp0;
02653 if (!nd) {
02654 for(; c == '0'; c = *++s)
02655 nz++;
02656 if (c > '0' && c <= '9') {
02657 bc.dp0 = s0 - s;
02658 bc.dp1 = bc.dp0 + bc.dplen;
02659 s0 = s;
02660 nf += nz;
02661 nz = 0;
02662 goto have_dig;
02663 }
02664 goto dig_done;
02665 }
02666 for(; c >= '0' && c <= '9'; c = *++s) {
02667 have_dig:
02668 nz++;
02669 if (c -= '0') {
02670 nf += nz;
02671 for(i = 1; i < nz; i++)
02672 if (nd++ < 9)
02673 y *= 10;
02674 else if (nd <= DBL_DIG + 1)
02675 z *= 10;
02676 if (nd++ < 9)
02677 y = 10*y + c;
02678 else if (nd <= DBL_DIG + 1)
02679 z = 10*z + c;
02680 nz = nz1 = 0;
02681 }
02682 }
02683 }
02684 dig_done:
02685 e = 0;
02686 if (c == 'e' || c == 'E') {
02687 if (!nd && !nz && !nz0) {
02688 goto ret0;
02689 }
02690 s00 = s;
02691 esign = 0;
02692 switch(c = *++s) {
02693 case '-':
02694 esign = 1;
02695 case '+':
02696 c = *++s;
02697 }
02698 if (c >= '0' && c <= '9') {
02699 while(c == '0')
02700 c = *++s;
02701 if (c > '0' && c <= '9') {
02702 L = c - '0';
02703 s1 = s;
02704 while((c = *++s) >= '0' && c <= '9')
02705 L = 10*L + c - '0';
02706 if (s - s1 > 8 || L > 19999)
02707
02708
02709
02710 e = 19999;
02711 else
02712 e = (int)L;
02713 if (esign)
02714 e = -e;
02715 }
02716 else
02717 e = 0;
02718 }
02719 else
02720 s = s00;
02721 }
02722 if (!nd) {
02723 if (!nz && !nz0) {
02724 #ifdef INFNAN_CHECK
02725
02726 if (!bc.dplen)
02727 switch(c) {
02728 case 'i':
02729 case 'I':
02730 if (match(&s,"nf")) {
02731 --s;
02732 if (!match(&s,"inity"))
02733 ++s;
02734 word0(&rv) = 0x7ff00000;
02735 word1(&rv) = 0;
02736 goto ret;
02737 }
02738 break;
02739 case 'n':
02740 case 'N':
02741 if (match(&s, "an")) {
02742 word0(&rv) = NAN_WORD0;
02743 word1(&rv) = NAN_WORD1;
02744 #ifndef No_Hex_NaN
02745 if (*s == '(')
02746 hexnan(&rv, &s);
02747 #endif
02748 goto ret;
02749 }
02750 }
02751 #endif
02752 ret0:
02753 s = s00;
02754 sign = 0;
02755 }
02756 goto ret;
02757 }
02758 bc.e0 = e1 = e -= nf;
02759
02760
02761
02762
02763
02764
02765 if (!nd0)
02766 nd0 = nd;
02767 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
02768 dval(&rv) = y;
02769 if (k > 9) {
02770 #ifdef SET_INEXACT
02771 if (k > DBL_DIG)
02772 oldinexact = get_inexact();
02773 #endif
02774 dval(&rv) = tens[k - 9] * dval(&rv) + z;
02775 }
02776 bd0 = 0;
02777 if (nd <= DBL_DIG
02778 #ifndef RND_PRODQUOT
02779 #ifndef Honor_FLT_ROUNDS
02780 && Flt_Rounds == 1
02781 #endif
02782 #endif
02783 ) {
02784 if (!e)
02785 goto ret;
02786 #ifndef ROUND_BIASED_without_Round_Up
02787 if (e > 0) {
02788 if (e <= Ten_pmax) {
02789 #ifdef VAX
02790 goto vax_ovfl_check;
02791 #else
02792 #ifdef Honor_FLT_ROUNDS
02793
02794 if (sign) {
02795 rv.d = -rv.d;
02796 sign = 0;
02797 }
02798 #endif
02799 rounded_product(dval(&rv), tens[e]);
02800 goto ret;
02801 #endif
02802 }
02803 i = DBL_DIG - nd;
02804 if (e <= Ten_pmax + i) {
02805
02806
02807
02808 #ifdef Honor_FLT_ROUNDS
02809
02810 if (sign) {
02811 rv.d = -rv.d;
02812 sign = 0;
02813 }
02814 #endif
02815 e -= i;
02816 dval(&rv) *= tens[i];
02817 #ifdef VAX
02818
02819
02820
02821 vax_ovfl_check:
02822 word0(&rv) -= P*Exp_msk1;
02823 rounded_product(dval(&rv), tens[e]);
02824 if ((word0(&rv) & Exp_mask)
02825 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
02826 goto ovfl;
02827 word0(&rv) += P*Exp_msk1;
02828 #else
02829 rounded_product(dval(&rv), tens[e]);
02830 #endif
02831 goto ret;
02832 }
02833 }
02834 #ifndef Inaccurate_Divide
02835 else if (e >= -Ten_pmax) {
02836 #ifdef Honor_FLT_ROUNDS
02837
02838 if (sign) {
02839 rv.d = -rv.d;
02840 sign = 0;
02841 }
02842 #endif
02843 rounded_quotient(dval(&rv), tens[-e]);
02844 goto ret;
02845 }
02846 #endif
02847 #endif
02848 }
02849 e1 += nd - k;
02850
02851 #ifdef IEEE_Arith
02852 #ifdef SET_INEXACT
02853 bc.inexact = 1;
02854 if (k <= DBL_DIG)
02855 oldinexact = get_inexact();
02856 #endif
02857 #ifdef Avoid_Underflow
02858 bc.scale = 0;
02859 #endif
02860 #ifdef Honor_FLT_ROUNDS
02861 if (bc.rounding >= 2) {
02862 if (sign)
02863 bc.rounding = bc.rounding == 2 ? 0 : 2;
02864 else
02865 if (bc.rounding != 2)
02866 bc.rounding = 0;
02867 }
02868 #endif
02869 #endif
02870
02871
02872
02873 if (e1 > 0) {
02874 if ((i = e1 & 15))
02875 dval(&rv) *= tens[i];
02876 if (e1 &= ~15) {
02877 if (e1 > DBL_MAX_10_EXP) {
02878 ovfl:
02879
02880 #ifdef IEEE_Arith
02881 #ifdef Honor_FLT_ROUNDS
02882 switch(bc.rounding) {
02883 case 0:
02884 case 3:
02885 word0(&rv) = Big0;
02886 word1(&rv) = Big1;
02887 break;
02888 default:
02889 word0(&rv) = Exp_mask;
02890 word1(&rv) = 0;
02891 }
02892 #else
02893 word0(&rv) = Exp_mask;
02894 word1(&rv) = 0;
02895 #endif
02896 #ifdef SET_INEXACT
02897
02898 dval(&rv0) = 1e300;
02899 dval(&rv0) *= dval(&rv0);
02900 #endif
02901 #else
02902 word0(&rv) = Big0;
02903 word1(&rv) = Big1;
02904 #endif
02905 range_err:
02906 if (bd0) {
02907 Bfree(bb);
02908 Bfree(bd);
02909 Bfree(bs);
02910 Bfree(bd0);
02911 Bfree(delta);
02912 }
02913 #ifndef NO_ERRNO
02914 errno = ERANGE;
02915 #endif
02916 goto ret;
02917 }
02918 e1 >>= 4;
02919 for(j = 0; e1 > 1; j++, e1 >>= 1)
02920 if (e1 & 1)
02921 dval(&rv) *= bigtens[j];
02922
02923 word0(&rv) -= P*Exp_msk1;
02924 dval(&rv) *= bigtens[j];
02925 if ((z = word0(&rv) & Exp_mask)
02926 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
02927 goto ovfl;
02928 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
02929
02930
02931 word0(&rv) = Big0;
02932 word1(&rv) = Big1;
02933 }
02934 else
02935 word0(&rv) += P*Exp_msk1;
02936 }
02937 }
02938 else if (e1 < 0) {
02939 e1 = -e1;
02940 if ((i = e1 & 15))
02941 dval(&rv) /= tens[i];
02942 if (e1 >>= 4) {
02943 if (e1 >= 1 << n_bigtens)
02944 goto undfl;
02945 #ifdef Avoid_Underflow
02946 if (e1 & Scale_Bit)
02947 bc.scale = 2*P;
02948 for(j = 0; e1 > 0; j++, e1 >>= 1)
02949 if (e1 & 1)
02950 dval(&rv) *= tinytens[j];
02951 if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask)
02952 >> Exp_shift)) > 0) {
02953
02954 if (j >= 32) {
02955 if (j > 54)
02956 goto undfl;
02957 word1(&rv) = 0;
02958 if (j >= 53)
02959 word0(&rv) = (P+2)*Exp_msk1;
02960 else
02961 word0(&rv) &= 0xffffffff << (j-32);
02962 }
02963 else
02964 word1(&rv) &= 0xffffffff << j;
02965 }
02966 #else
02967 for(j = 0; e1 > 1; j++, e1 >>= 1)
02968 if (e1 & 1)
02969 dval(&rv) *= tinytens[j];
02970
02971 dval(&rv0) = dval(&rv);
02972 dval(&rv) *= tinytens[j];
02973 if (!dval(&rv)) {
02974 dval(&rv) = 2.*dval(&rv0);
02975 dval(&rv) *= tinytens[j];
02976 #endif
02977 if (!dval(&rv)) {
02978 undfl:
02979 dval(&rv) = 0.;
02980 goto range_err;
02981 }
02982 #ifndef Avoid_Underflow
02983 word0(&rv) = Tiny0;
02984 word1(&rv) = Tiny1;
02985
02986
02987
02988 }
02989 #endif
02990 }
02991 }
02992
02993
02994
02995
02996
02997 bc.nd = nd - nz1;
02998 #ifndef NO_STRTOD_BIGCOMP
02999 bc.nd0 = nd0;
03000
03001
03002 if (nd > strtod_diglim) {
03003
03004
03005
03006 i = j = 18;
03007 if (i > nd0)
03008 j += bc.dplen;
03009 for(;;) {
03010 if (--j < bc.dp1 && j >= bc.dp0)
03011 j = bc.dp0 - 1;
03012 if (s0[j] != '0')
03013 break;
03014 --i;
03015 }
03016 e += nd - i;
03017 nd = i;
03018 if (nd0 > nd)
03019 nd0 = nd;
03020 if (nd < 9) {
03021 y = 0;
03022 for(i = 0; i < nd0; ++i)
03023 y = 10*y + s0[i] - '0';
03024 for(j = bc.dp1; i < nd; ++i)
03025 y = 10*y + s0[j++] - '0';
03026 }
03027 }
03028 #endif
03029 bd0 = s2b(s0, nd0, nd, y, bc.dplen);
03030
03031 for(;;) {
03032 bd = Balloc(bd0->k);
03033 Bcopy(bd, bd0);
03034 bb = d2b(&rv, &bbe, &bbbits);
03035 bs = i2b(1);
03036
03037 if (e >= 0) {
03038 bb2 = bb5 = 0;
03039 bd2 = bd5 = e;
03040 }
03041 else {
03042 bb2 = bb5 = -e;
03043 bd2 = bd5 = 0;
03044 }
03045 if (bbe >= 0)
03046 bb2 += bbe;
03047 else
03048 bd2 -= bbe;
03049 bs2 = bb2;
03050 #ifdef Honor_FLT_ROUNDS
03051 if (bc.rounding != 1)
03052 bs2++;
03053 #endif
03054 #ifdef Avoid_Underflow
03055 Lsb = LSB;
03056 Lsb1 = 0;
03057 j = bbe - bc.scale;
03058 i = j + bbbits - 1;
03059 j = P + 1 - bbbits;
03060 if (i < Emin) {
03061 i = Emin - i;
03062 j -= i;
03063 if (i < 32)
03064 Lsb <<= i;
03065 else if (i < 52)
03066 Lsb1 = Lsb << (i-32);
03067 else
03068 Lsb1 = Exp_mask;
03069 }
03070 #else
03071 #ifdef Sudden_Underflow
03072 #ifdef IBM
03073 j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
03074 #else
03075 j = P + 1 - bbbits;
03076 #endif
03077 #else
03078 j = bbe;
03079 i = j + bbbits - 1;
03080 if (i < Emin)
03081 j += P - Emin;
03082 else
03083 j = P + 1 - bbbits;
03084 #endif
03085 #endif
03086 bb2 += j;
03087 bd2 += j;
03088 #ifdef Avoid_Underflow
03089 bd2 += bc.scale;
03090 #endif
03091 i = bb2 < bd2 ? bb2 : bd2;
03092 if (i > bs2)
03093 i = bs2;
03094 if (i > 0) {
03095 bb2 -= i;
03096 bd2 -= i;
03097 bs2 -= i;
03098 }
03099 if (bb5 > 0) {
03100 bs = pow5mult(bs, bb5);
03101 bb1 = mult(bs, bb);
03102 Bfree(bb);
03103 bb = bb1;
03104 }
03105 if (bb2 > 0)
03106 bb = lshift(bb, bb2);
03107 if (bd5 > 0)
03108 bd = pow5mult(bd, bd5);
03109 if (bd2 > 0)
03110 bd = lshift(bd, bd2);
03111 if (bs2 > 0)
03112 bs = lshift(bs, bs2);
03113 delta = diff(bb, bd);
03114 bc.dsign = delta->sign;
03115 delta->sign = 0;
03116 i = cmp(delta, bs);
03117 #ifndef NO_STRTOD_BIGCOMP
03118 if (bc.nd > nd && i <= 0) {
03119 if (bc.dsign) {
03120
03121 req_bigcomp = 1;
03122 break;
03123 }
03124 #ifdef Honor_FLT_ROUNDS
03125 if (bc.rounding != 1) {
03126 if (i < 0) {
03127 req_bigcomp = 1;
03128 break;
03129 }
03130 }
03131 else
03132 #endif
03133 i = -1;
03134 }
03135 #endif
03136 #ifdef Honor_FLT_ROUNDS
03137 if (bc.rounding != 1) {
03138 if (i < 0) {
03139
03140 if (!delta->x[0] && delta->wds <= 1) {
03141
03142 #ifdef SET_INEXACT
03143 bc.inexact = 0;
03144 #endif
03145 break;
03146 }
03147 if (bc.rounding) {
03148 if (bc.dsign) {
03149 adj.d = 1.;
03150 goto apply_adj;
03151 }
03152 }
03153 else if (!bc.dsign) {
03154 adj.d = -1.;
03155 if (!word1(&rv)
03156 && !(word0(&rv) & Frac_mask)) {
03157 y = word0(&rv) & Exp_mask;
03158 #ifdef Avoid_Underflow
03159 if (!bc.scale || y > 2*P*Exp_msk1)
03160 #else
03161 if (y)
03162 #endif
03163 {
03164 delta = lshift(delta,Log2P);
03165 if (cmp(delta, bs) <= 0)
03166 adj.d = -0.5;
03167 }
03168 }
03169 apply_adj:
03170 #ifdef Avoid_Underflow
03171 if (bc.scale && (y = word0(&rv) & Exp_mask)
03172 <= 2*P*Exp_msk1)
03173 word0(&adj) += (2*P+1)*Exp_msk1 - y;
03174 #else
03175 #ifdef Sudden_Underflow
03176 if ((word0(&rv) & Exp_mask) <=
03177 P*Exp_msk1) {
03178 word0(&rv) += P*Exp_msk1;
03179 dval(&rv) += adj.d*ulp(dval(&rv));
03180 word0(&rv) -= P*Exp_msk1;
03181 }
03182 else
03183 #endif
03184 #endif
03185 dval(&rv) += adj.d*ulp(&rv);
03186 }
03187 break;
03188 }
03189 adj.d = ratio(delta, bs);
03190 if (adj.d < 1.)
03191 adj.d = 1.;
03192 if (adj.d <= 0x7ffffffe) {
03193
03194 y = adj.d;
03195 if (y != adj.d) {
03196 if (!((bc.rounding>>1) ^ bc.dsign))
03197 y++;
03198 adj.d = y;
03199 }
03200 }
03201 #ifdef Avoid_Underflow
03202 if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
03203 word0(&adj) += (2*P+1)*Exp_msk1 - y;
03204 #else
03205 #ifdef Sudden_Underflow
03206 if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
03207 word0(&rv) += P*Exp_msk1;
03208 adj.d *= ulp(dval(&rv));
03209 if (bc.dsign)
03210 dval(&rv) += adj.d;
03211 else
03212 dval(&rv) -= adj.d;
03213 word0(&rv) -= P*Exp_msk1;
03214 goto cont;
03215 }
03216 #endif
03217 #endif
03218 adj.d *= ulp(&rv);
03219 if (bc.dsign) {
03220 if (word0(&rv) == Big0 && word1(&rv) == Big1)
03221 goto ovfl;
03222 dval(&rv) += adj.d;
03223 }
03224 else
03225 dval(&rv) -= adj.d;
03226 goto cont;
03227 }
03228 #endif
03229
03230 if (i < 0) {
03231
03232
03233
03234 if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask
03235 #ifdef IEEE_Arith
03236 #ifdef Avoid_Underflow
03237 || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
03238 #else
03239 || (word0(&rv) & Exp_mask) <= Exp_msk1
03240 #endif
03241 #endif
03242 ) {
03243 #ifdef SET_INEXACT
03244 if (!delta->x[0] && delta->wds <= 1)
03245 bc.inexact = 0;
03246 #endif
03247 break;
03248 }
03249 if (!delta->x[0] && delta->wds <= 1) {
03250
03251 #ifdef SET_INEXACT
03252 bc.inexact = 0;
03253 #endif
03254 break;
03255 }
03256 delta = lshift(delta,Log2P);
03257 if (cmp(delta, bs) > 0)
03258 goto drop_down;
03259 break;
03260 }
03261 if (i == 0) {
03262
03263 if (bc.dsign) {
03264 if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
03265 && word1(&rv) == (
03266 #ifdef Avoid_Underflow
03267 (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
03268 ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
03269 #endif
03270 0xffffffff)) {
03271
03272 if (word0(&rv) == Big0 && word1(&rv) == Big1)
03273 goto ovfl;
03274 word0(&rv) = (word0(&rv) & Exp_mask)
03275 + Exp_msk1
03276 #ifdef IBM
03277 | Exp_msk1 >> 4
03278 #endif
03279 ;
03280 word1(&rv) = 0;
03281 #ifdef Avoid_Underflow
03282 bc.dsign = 0;
03283 #endif
03284 break;
03285 }
03286 }
03287 else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
03288 drop_down:
03289
03290 #ifdef Sudden_Underflow
03291 L = word0(&rv) & Exp_mask;
03292 #ifdef IBM
03293 if (L < Exp_msk1)
03294 #else
03295 #ifdef Avoid_Underflow
03296 if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
03297 #else
03298 if (L <= Exp_msk1)
03299 #endif
03300 #endif
03301 {
03302 if (bc.nd >nd) {
03303 bc.uflchk = 1;
03304 break;
03305 }
03306 goto undfl;
03307 }
03308 L -= Exp_msk1;
03309 #else
03310 #ifdef Avoid_Underflow
03311 if (bc.scale) {
03312 L = word0(&rv) & Exp_mask;
03313 if (L <= (2*P+1)*Exp_msk1) {
03314 if (L > (P+2)*Exp_msk1)
03315
03316
03317 break;
03318
03319 if (bc.nd >nd) {
03320 bc.uflchk = 1;
03321 break;
03322 }
03323 goto undfl;
03324 }
03325 }
03326 #endif
03327 L = (word0(&rv) & Exp_mask) - Exp_msk1;
03328 #endif
03329 word0(&rv) = L | Bndry_mask1;
03330 word1(&rv) = 0xffffffff;
03331 #ifdef IBM
03332 goto cont;
03333 #else
03334 #ifndef NO_STRTOD_BIGCOMP
03335 if (bc.nd > nd)
03336 goto cont;
03337 #endif
03338 break;
03339 #endif
03340 }
03341 #ifndef ROUND_BIASED
03342 #ifdef Avoid_Underflow
03343 if (Lsb1) {
03344 if (!(word0(&rv) & Lsb1))
03345 break;
03346 }
03347 else if (!(word1(&rv) & Lsb))
03348 break;
03349 #else
03350 if (!(word1(&rv) & LSB))
03351 break;
03352 #endif
03353 #endif
03354 if (bc.dsign)
03355 #ifdef Avoid_Underflow
03356 dval(&rv) += sulp(&rv, &bc);
03357 #else
03358 dval(&rv) += ulp(&rv);
03359 #endif
03360 #ifndef ROUND_BIASED
03361 else {
03362 #ifdef Avoid_Underflow
03363 dval(&rv) -= sulp(&rv, &bc);
03364 #else
03365 dval(&rv) -= ulp(&rv);
03366 #endif
03367 #ifndef Sudden_Underflow
03368 if (!dval(&rv)) {
03369 if (bc.nd >nd) {
03370 bc.uflchk = 1;
03371 break;
03372 }
03373 goto undfl;
03374 }
03375 #endif
03376 }
03377 #ifdef Avoid_Underflow
03378 bc.dsign = 1 - bc.dsign;
03379 #endif
03380 #endif
03381 break;
03382 }
03383 if ((aadj = ratio(delta, bs)) <= 2.) {
03384 if (bc.dsign)
03385 aadj = aadj1 = 1.;
03386 else if (word1(&rv) || word0(&rv) & Bndry_mask) {
03387 #ifndef Sudden_Underflow
03388 if (word1(&rv) == Tiny1 && !word0(&rv)) {
03389 if (bc.nd >nd) {
03390 bc.uflchk = 1;
03391 break;
03392 }
03393 goto undfl;
03394 }
03395 #endif
03396 aadj = 1.;
03397 aadj1 = -1.;
03398 }
03399 else {
03400
03401
03402
03403 if (aadj < 2./FLT_RADIX)
03404 aadj = 1./FLT_RADIX;
03405 else
03406 aadj *= 0.5;
03407 aadj1 = -aadj;
03408 }
03409 }
03410 else {
03411 aadj *= 0.5;
03412 aadj1 = bc.dsign ? aadj : -aadj;
03413 #ifdef Check_FLT_ROUNDS
03414 switch(bc.rounding) {
03415 case 2:
03416 aadj1 -= 0.5;
03417 break;
03418 case 0:
03419 case 3:
03420 aadj1 += 0.5;
03421 }
03422 #else
03423 if (Flt_Rounds == 0)
03424 aadj1 += 0.5;
03425 #endif
03426 }
03427 y = word0(&rv) & Exp_mask;
03428
03429
03430
03431 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
03432 dval(&rv0) = dval(&rv);
03433 word0(&rv) -= P*Exp_msk1;
03434 adj.d = aadj1 * ulp(&rv);
03435 dval(&rv) += adj.d;
03436 if ((word0(&rv) & Exp_mask) >=
03437 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
03438 if (word0(&rv0) == Big0 && word1(&rv0) == Big1)
03439 goto ovfl;
03440 word0(&rv) = Big0;
03441 word1(&rv) = Big1;
03442 goto cont;
03443 }
03444 else
03445 word0(&rv) += P*Exp_msk1;
03446 }
03447 else {
03448 #ifdef Avoid_Underflow
03449 if (bc.scale && y <= 2*P*Exp_msk1) {
03450 if (aadj <= 0x7fffffff) {
03451 if ((z = aadj) <= 0)
03452 z = 1;
03453 aadj = z;
03454 aadj1 = bc.dsign ? aadj : -aadj;
03455 }
03456 dval(&aadj2) = aadj1;
03457 word0(&aadj2) += (2*P+1)*Exp_msk1 - y;
03458 aadj1 = dval(&aadj2);
03459 adj.d = aadj1 * ulp(&rv);
03460 dval(&rv) += adj.d;
03461 if (rv.d == 0.)
03462 #ifdef NO_STRTOD_BIGCOMP
03463 goto undfl;
03464 #else
03465 {
03466 if (bc.nd > nd)
03467 bc.dsign = 1;
03468 break;
03469 }
03470 #endif
03471 }
03472 else {
03473 adj.d = aadj1 * ulp(&rv);
03474 dval(&rv) += adj.d;
03475 }
03476 #else
03477 #ifdef Sudden_Underflow
03478 if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
03479 dval(&rv0) = dval(&rv);
03480 word0(&rv) += P*Exp_msk1;
03481 adj.d = aadj1 * ulp(&rv);
03482 dval(&rv) += adj.d;
03483 #ifdef IBM
03484 if ((word0(&rv) & Exp_mask) < P*Exp_msk1)
03485 #else
03486 if ((word0(&rv) & Exp_mask) <= P*Exp_msk1)
03487 #endif
03488 {
03489 if (word0(&rv0) == Tiny0
03490 && word1(&rv0) == Tiny1) {
03491 if (bc.nd >nd) {
03492 bc.uflchk = 1;
03493 break;
03494 }
03495 goto undfl;
03496 }
03497 word0(&rv) = Tiny0;
03498 word1(&rv) = Tiny1;
03499 goto cont;
03500 }
03501 else
03502 word0(&rv) -= P*Exp_msk1;
03503 }
03504 else {
03505 adj.d = aadj1 * ulp(&rv);
03506 dval(&rv) += adj.d;
03507 }
03508 #else
03509
03510
03511
03512
03513
03514
03515
03516 if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
03517 aadj1 = (double)(int)(aadj + 0.5);
03518 if (!bc.dsign)
03519 aadj1 = -aadj1;
03520 }
03521 adj.d = aadj1 * ulp(&rv);
03522 dval(&rv) += adj.d;
03523 #endif
03524 #endif
03525 }
03526 z = word0(&rv) & Exp_mask;
03527 #ifndef SET_INEXACT
03528 if (bc.nd == nd) {
03529 #ifdef Avoid_Underflow
03530 if (!bc.scale)
03531 #endif
03532 if (y == z) {
03533
03534 L = (Long)aadj;
03535 aadj -= L;
03536
03537 if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
03538 if (aadj < .4999999 || aadj > .5000001)
03539 break;
03540 }
03541 else if (aadj < .4999999/FLT_RADIX)
03542 break;
03543 }
03544 }
03545 #endif
03546 cont:
03547 Bfree(bb);
03548 Bfree(bd);
03549 Bfree(bs);
03550 Bfree(delta);
03551 }
03552 Bfree(bb);
03553 Bfree(bd);
03554 Bfree(bs);
03555 Bfree(bd0);
03556 Bfree(delta);
03557 #ifndef NO_STRTOD_BIGCOMP
03558 if (req_bigcomp) {
03559 bd0 = 0;
03560 bc.e0 += nz1;
03561 bigcomp(&rv, s0, &bc);
03562 y = word0(&rv) & Exp_mask;
03563 if (y == Exp_mask)
03564 goto ovfl;
03565 if (y == 0 && rv.d == 0.)
03566 goto undfl;
03567 }
03568 #endif
03569 #ifdef SET_INEXACT
03570 if (bc.inexact) {
03571 if (!oldinexact) {
03572 word0(&rv0) = Exp_1 + (70 << Exp_shift);
03573 word1(&rv0) = 0;
03574 dval(&rv0) += 1.;
03575 }
03576 }
03577 else if (!oldinexact)
03578 clear_inexact();
03579 #endif
03580 #ifdef Avoid_Underflow
03581 if (bc.scale) {
03582 word0(&rv0) = Exp_1 - 2*P*Exp_msk1;
03583 word1(&rv0) = 0;
03584 dval(&rv) *= dval(&rv0);
03585 #ifndef NO_ERRNO
03586
03587 #ifdef IEEE_Arith
03588 if (!(word0(&rv) & Exp_mask))
03589 #else
03590 if (word0(&rv) == 0 && word1(&rv) == 0)
03591 #endif
03592 errno = ERANGE;
03593 #endif
03594 }
03595 #endif
03596 #ifdef SET_INEXACT
03597 if (bc.inexact && !(word0(&rv) & Exp_mask)) {
03598
03599 dval(&rv0) = 1e-300;
03600 dval(&rv0) *= dval(&rv0);
03601 }
03602 #endif
03603 ret:
03604 if (se)
03605 *se = (char *)s;
03606 return sign ? -dval(&rv) : dval(&rv);
03607 }
03608
03609 #ifndef MULTIPLE_THREADS
03610 static char *dtoa_result;
03611 #endif
03612
03613 static char *
03614 #ifdef KR_headers
03615 rv_alloc(i) int i;
03616 #else
03617 rv_alloc(int i)
03618 #endif
03619 {
03620 int j, k, *r;
03621
03622 j = sizeof(ULong);
03623 for(k = 0;
03624 sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
03625 j <<= 1)
03626 k++;
03627 r = (int*)Balloc(k);
03628 *r = k;
03629 return
03630 #ifndef MULTIPLE_THREADS
03631 dtoa_result =
03632 #endif
03633 (char *)(r+1);
03634 }
03635
03636 static char *
03637 #ifdef KR_headers
03638 nrv_alloc(s, rve, n) char *s, **rve; int n;
03639 #else
03640 nrv_alloc(const char *s, char **rve, int n)
03641 #endif
03642 {
03643 char *rv, *t;
03644
03645 t = rv = rv_alloc(n);
03646 while((*t = *s++)) t++;
03647 if (rve)
03648 *rve = t;
03649 return rv;
03650 }
03651
03652
03653
03654
03655
03656
03657
03658 void
03659 #ifdef KR_headers
03660 os_freedtoa(s) char *s;
03661 #else
03662 os_freedtoa(char *s)
03663 #endif
03664 {
03665 Bigint *b = (Bigint *)((int *)s - 1);
03666 b->maxwds = 1 << (b->k = *(int*)b);
03667 Bfree(b);
03668 #ifndef MULTIPLE_THREADS
03669 if (s == dtoa_result)
03670 dtoa_result = 0;
03671 #endif
03672 }
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708 char *
03709 os_dtoa
03710 #ifdef KR_headers
03711 (dd, mode, ndigits, decpt, sign, rve)
03712 double dd; int mode, ndigits, *decpt, *sign; char **rve;
03713 #else
03714 (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
03715 #endif
03716 {
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
03752 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
03753 spec_case, try_quick;
03754 Long L;
03755 #ifndef Sudden_Underflow
03756 int denorm;
03757 ULong x;
03758 #endif
03759 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
03760 U d2, eps, u;
03761 double ds;
03762 char *s, *s0;
03763 #ifndef No_leftright
03764 #ifdef IEEE_Arith
03765 U eps1;
03766 #endif
03767 #endif
03768 #ifdef SET_INEXACT
03769 int inexact, oldinexact;
03770 #endif
03771 #ifdef Honor_FLT_ROUNDS
03772 int Rounding;
03773 #ifdef Trust_FLT_ROUNDS
03774 Rounding = Flt_Rounds;
03775 #else
03776 Rounding = 1;
03777 switch(fegetround()) {
03778 case FE_TOWARDZERO: Rounding = 0; break;
03779 case FE_UPWARD: Rounding = 2; break;
03780 case FE_DOWNWARD: Rounding = 3;
03781 }
03782 #endif
03783 #endif
03784
03785 #ifndef MULTIPLE_THREADS
03786 if (dtoa_result) {
03787 os_freedtoa(dtoa_result);
03788 dtoa_result = 0;
03789 }
03790 #endif
03791
03792 u.d = dd;
03793 if (word0(&u) & Sign_bit) {
03794
03795 *sign = 1;
03796 word0(&u) &= ~Sign_bit;
03797 }
03798 else
03799 *sign = 0;
03800
03801 #if defined(IEEE_Arith) + defined(VAX)
03802 #ifdef IEEE_Arith
03803 if ((word0(&u) & Exp_mask) == Exp_mask)
03804 #else
03805 if (word0(&u) == 0x8000)
03806 #endif
03807 {
03808
03809 *decpt = 9999;
03810 #ifdef IEEE_Arith
03811 if (!word1(&u) && !(word0(&u) & 0xfffff))
03812 return nrv_alloc("Infinity", rve, 8);
03813 #endif
03814 return nrv_alloc("NaN", rve, 3);
03815 }
03816 #endif
03817 #ifdef IBM
03818 dval(&u) += 0;
03819 #endif
03820 if (!dval(&u)) {
03821 *decpt = 1;
03822 return nrv_alloc("0", rve, 1);
03823 }
03824
03825 #ifdef SET_INEXACT
03826 try_quick = oldinexact = get_inexact();
03827 inexact = 1;
03828 #endif
03829 #ifdef Honor_FLT_ROUNDS
03830 if (Rounding >= 2) {
03831 if (*sign)
03832 Rounding = Rounding == 2 ? 0 : 2;
03833 else
03834 if (Rounding != 2)
03835 Rounding = 0;
03836 }
03837 #endif
03838
03839 b = d2b(&u, &be, &bbits);
03840 #ifdef Sudden_Underflow
03841 i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
03842 #else
03843 if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
03844 #endif
03845 dval(&d2) = dval(&u);
03846 word0(&d2) &= Frac_mask1;
03847 word0(&d2) |= Exp_11;
03848 #ifdef IBM
03849 if (j = 11 - hi0bits(word0(&d2) & Frac_mask))
03850 dval(&d2) /= 1 << j;
03851 #endif
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875 i -= Bias;
03876 #ifdef IBM
03877 i <<= 2;
03878 i += j;
03879 #endif
03880 #ifndef Sudden_Underflow
03881 denorm = 0;
03882 }
03883 else {
03884
03885
03886 i = bbits + be + (Bias + (P-1) - 1);
03887 x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32)
03888 : word1(&u) << (32 - i);
03889 dval(&d2) = x;
03890 word0(&d2) -= 31*Exp_msk1;
03891 i -= (Bias + (P-1) - 1) + 1;
03892 denorm = 1;
03893 }
03894 #endif
03895 ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
03896 k = (int)ds;
03897 if (ds < 0. && ds != k)
03898 k--;
03899 k_check = 1;
03900 if (k >= 0 && k <= Ten_pmax) {
03901 if (dval(&u) < tens[k])
03902 k--;
03903 k_check = 0;
03904 }
03905 j = bbits - i - 1;
03906 if (j >= 0) {
03907 b2 = 0;
03908 s2 = j;
03909 }
03910 else {
03911 b2 = -j;
03912 s2 = 0;
03913 }
03914 if (k >= 0) {
03915 b5 = 0;
03916 s5 = k;
03917 s2 += k;
03918 }
03919 else {
03920 b2 -= k;
03921 b5 = -k;
03922 s5 = 0;
03923 }
03924 if (mode < 0 || mode > 9)
03925 mode = 0;
03926
03927 #ifndef SET_INEXACT
03928 #ifdef Check_FLT_ROUNDS
03929 try_quick = Rounding == 1;
03930 #else
03931 try_quick = 1;
03932 #endif
03933 #endif
03934
03935 if (mode > 5) {
03936 mode -= 4;
03937 try_quick = 0;
03938 }
03939 leftright = 1;
03940 ilim = ilim1 = -1;
03941
03942 switch(mode) {
03943 case 0:
03944 case 1:
03945 i = 18;
03946 ndigits = 0;
03947 break;
03948 case 2:
03949 leftright = 0;
03950
03951 case 4:
03952 if (ndigits <= 0)
03953 ndigits = 1;
03954 ilim = ilim1 = i = ndigits;
03955 break;
03956 case 3:
03957 leftright = 0;
03958
03959 case 5:
03960 i = ndigits + k + 1;
03961 ilim = i;
03962 ilim1 = i - 1;
03963 if (i <= 0)
03964 i = 1;
03965 }
03966 s = s0 = rv_alloc(i);
03967
03968 #ifdef Honor_FLT_ROUNDS
03969 if (mode > 1 && Rounding != 1)
03970 leftright = 0;
03971 #endif
03972
03973 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
03974
03975
03976
03977 i = 0;
03978 dval(&d2) = dval(&u);
03979 k0 = k;
03980 ilim0 = ilim;
03981 ieps = 2;
03982 if (k > 0) {
03983 ds = tens[k&0xf];
03984 j = k >> 4;
03985 if (j & Bletch) {
03986
03987 j &= Bletch - 1;
03988 dval(&u) /= bigtens[n_bigtens-1];
03989 ieps++;
03990 }
03991 for(; j; j >>= 1, i++)
03992 if (j & 1) {
03993 ieps++;
03994 ds *= bigtens[i];
03995 }
03996 dval(&u) /= ds;
03997 }
03998 else if ((j1 = -k)) {
03999 dval(&u) *= tens[j1 & 0xf];
04000 for(j = j1 >> 4; j; j >>= 1, i++)
04001 if (j & 1) {
04002 ieps++;
04003 dval(&u) *= bigtens[i];
04004 }
04005 }
04006 if (k_check && dval(&u) < 1. && ilim > 0) {
04007 if (ilim1 <= 0)
04008 goto fast_failed;
04009 ilim = ilim1;
04010 k--;
04011 dval(&u) *= 10.;
04012 ieps++;
04013 }
04014 dval(&eps) = ieps*dval(&u) + 7.;
04015 word0(&eps) -= (P-1)*Exp_msk1;
04016 if (ilim == 0) {
04017 S = mhi = 0;
04018 dval(&u) -= 5.;
04019 if (dval(&u) > dval(&eps))
04020 goto one_digit;
04021 if (dval(&u) < -dval(&eps))
04022 goto no_digits;
04023 goto fast_failed;
04024 }
04025 #ifndef No_leftright
04026 if (leftright) {
04027
04028
04029
04030 dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
04031 #ifdef IEEE_Arith
04032 if (k0 < 0 && j1 >= 307) {
04033 eps1.d = 1.01e256;
04034 word0(&eps1) -= Exp_msk1 * (Bias+P-1);
04035 dval(&eps1) *= tens[j1 & 0xf];
04036 for(i = 0, j = (j1-256) >> 4; j; j >>= 1, i++)
04037 if (j & 1)
04038 dval(&eps1) *= bigtens[i];
04039 if (eps.d < eps1.d)
04040 eps.d = eps1.d;
04041 }
04042 #endif
04043 for(i = 0;;) {
04044 L = dval(&u);
04045 dval(&u) -= L;
04046 *s++ = '0' + (int)L;
04047 if (1. - dval(&u) < dval(&eps))
04048 goto bump_up;
04049 if (dval(&u) < dval(&eps))
04050 goto ret1;
04051 if (++i >= ilim)
04052 break;
04053 dval(&eps) *= 10.;
04054 dval(&u) *= 10.;
04055 }
04056 }
04057 else {
04058 #endif
04059
04060 dval(&eps) *= tens[ilim-1];
04061 for(i = 1;; i++, dval(&u) *= 10.) {
04062 L = (Long)(dval(&u));
04063 if (!(dval(&u) -= L))
04064 ilim = i;
04065 *s++ = '0' + (int)L;
04066 if (i == ilim) {
04067 if (dval(&u) > 0.5 + dval(&eps))
04068 goto bump_up;
04069 else if (dval(&u) < 0.5 - dval(&eps)) {
04070 while(*--s == '0');
04071 s++;
04072 goto ret1;
04073 }
04074 break;
04075 }
04076 }
04077 #ifndef No_leftright
04078 }
04079 #endif
04080 fast_failed:
04081 s = s0;
04082 dval(&u) = dval(&d2);
04083 k = k0;
04084 ilim = ilim0;
04085 }
04086
04087
04088
04089 if (be >= 0 && k <= Int_max) {
04090
04091 ds = tens[k];
04092 if (ndigits < 0 && ilim <= 0) {
04093 S = mhi = 0;
04094 if (ilim < 0 || dval(&u) <= 5*ds)
04095 goto no_digits;
04096 goto one_digit;
04097 }
04098 for(i = 1;; i++, dval(&u) *= 10.) {
04099 L = (Long)(dval(&u) / ds);
04100 dval(&u) -= L*ds;
04101 #ifdef Check_FLT_ROUNDS
04102
04103 if (dval(&u) < 0) {
04104 L--;
04105 dval(&u) += ds;
04106 }
04107 #endif
04108 *s++ = '0' + (int)L;
04109 if (!dval(&u)) {
04110 #ifdef SET_INEXACT
04111 inexact = 0;
04112 #endif
04113 break;
04114 }
04115 if (i == ilim) {
04116 #ifdef Honor_FLT_ROUNDS
04117 if (mode > 1)
04118 switch(Rounding) {
04119 case 0: goto ret1;
04120 case 2: goto bump_up;
04121 }
04122 #endif
04123 dval(&u) += dval(&u);
04124 #ifdef ROUND_BIASED
04125 if (dval(&u) >= ds)
04126 #else
04127 if (dval(&u) > ds || (dval(&u) == ds && L & 1))
04128 #endif
04129 {
04130 bump_up:
04131 while(*--s == '9')
04132 if (s == s0) {
04133 k++;
04134 *s = '0';
04135 break;
04136 }
04137 ++*s++;
04138 }
04139 break;
04140 }
04141 }
04142 goto ret1;
04143 }
04144
04145 m2 = b2;
04146 m5 = b5;
04147 mhi = mlo = 0;
04148 if (leftright) {
04149 i =
04150 #ifndef Sudden_Underflow
04151 denorm ? be + (Bias + (P-1) - 1 + 1) :
04152 #endif
04153 #ifdef IBM
04154 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
04155 #else
04156 1 + P - bbits;
04157 #endif
04158 b2 += i;
04159 s2 += i;
04160 mhi = i2b(1);
04161 }
04162 if (m2 > 0 && s2 > 0) {
04163 i = m2 < s2 ? m2 : s2;
04164 b2 -= i;
04165 m2 -= i;
04166 s2 -= i;
04167 }
04168 if (b5 > 0) {
04169 if (leftright) {
04170 if (m5 > 0) {
04171 mhi = pow5mult(mhi, m5);
04172 b1 = mult(mhi, b);
04173 Bfree(b);
04174 b = b1;
04175 }
04176 if ((j = b5 - m5))
04177 b = pow5mult(b, j);
04178 }
04179 else
04180 b = pow5mult(b, b5);
04181 }
04182 S = i2b(1);
04183 if (s5 > 0)
04184 S = pow5mult(S, s5);
04185
04186
04187
04188 spec_case = 0;
04189 if ((mode < 2 || leftright)
04190 #ifdef Honor_FLT_ROUNDS
04191 && Rounding == 1
04192 #endif
04193 ) {
04194 if (!word1(&u) && !(word0(&u) & Bndry_mask)
04195 #ifndef Sudden_Underflow
04196 && word0(&u) & (Exp_mask & ~Exp_msk1)
04197 #endif
04198 ) {
04199
04200 b2 += Log2P;
04201 s2 += Log2P;
04202 spec_case = 1;
04203 }
04204 }
04205
04206
04207
04208
04209
04210
04211
04212
04213 i = dshift(S, s2);
04214 b2 += i;
04215 m2 += i;
04216 s2 += i;
04217 if (b2 > 0)
04218 b = lshift(b, b2);
04219 if (s2 > 0)
04220 S = lshift(S, s2);
04221 if (k_check) {
04222 if (cmp(b,S) < 0) {
04223 k--;
04224 b = multadd(b, 10, 0);
04225 if (leftright)
04226 mhi = multadd(mhi, 10, 0);
04227 ilim = ilim1;
04228 }
04229 }
04230 if (ilim <= 0 && (mode == 3 || mode == 5)) {
04231 if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
04232
04233 no_digits:
04234 k = -1 - ndigits;
04235 goto ret;
04236 }
04237 one_digit:
04238 *s++ = '1';
04239 k++;
04240 goto ret;
04241 }
04242 if (leftright) {
04243 if (m2 > 0)
04244 mhi = lshift(mhi, m2);
04245
04246
04247
04248
04249
04250 mlo = mhi;
04251 if (spec_case) {
04252 mhi = Balloc(mhi->k);
04253 Bcopy(mhi, mlo);
04254 mhi = lshift(mhi, Log2P);
04255 }
04256
04257 for(i = 1;;i++) {
04258 dig = quorem(b,S) + '0';
04259
04260
04261
04262 j = cmp(b, mlo);
04263 delta = diff(S, mhi);
04264 j1 = delta->sign ? 1 : cmp(b, delta);
04265 Bfree(delta);
04266 #ifndef ROUND_BIASED
04267 if (j1 == 0 && mode != 1 && !(word1(&u) & 1)
04268 #ifdef Honor_FLT_ROUNDS
04269 && Rounding >= 1
04270 #endif
04271 ) {
04272 if (dig == '9')
04273 goto round_9_up;
04274 if (j > 0)
04275 dig++;
04276 #ifdef SET_INEXACT
04277 else if (!b->x[0] && b->wds <= 1)
04278 inexact = 0;
04279 #endif
04280 *s++ = dig;
04281 goto ret;
04282 }
04283 #endif
04284 if (j < 0 || (j == 0 && mode != 1
04285 #ifndef ROUND_BIASED
04286 && !(word1(&u) & 1)
04287 #endif
04288 )) {
04289 if (!b->x[0] && b->wds <= 1) {
04290 #ifdef SET_INEXACT
04291 inexact = 0;
04292 #endif
04293 goto accept_dig;
04294 }
04295 #ifdef Honor_FLT_ROUNDS
04296 if (mode > 1)
04297 switch(Rounding) {
04298 case 0: goto accept_dig;
04299 case 2: goto keep_dig;
04300 }
04301 #endif
04302 if (j1 > 0) {
04303 b = lshift(b, 1);
04304 j1 = cmp(b, S);
04305 #ifdef ROUND_BIASED
04306 if (j1 >= 0
04307 #else
04308 if ((j1 > 0 || (j1 == 0 && dig & 1))
04309 #endif
04310 && dig++ == '9')
04311 goto round_9_up;
04312 }
04313 accept_dig:
04314 *s++ = dig;
04315 goto ret;
04316 }
04317 if (j1 > 0) {
04318 #ifdef Honor_FLT_ROUNDS
04319 if (!Rounding)
04320 goto accept_dig;
04321 #endif
04322 if (dig == '9') {
04323 round_9_up:
04324 *s++ = '9';
04325 goto roundoff;
04326 }
04327 *s++ = dig + 1;
04328 goto ret;
04329 }
04330 #ifdef Honor_FLT_ROUNDS
04331 keep_dig:
04332 #endif
04333 *s++ = dig;
04334 if (i == ilim)
04335 break;
04336 b = multadd(b, 10, 0);
04337 if (mlo == mhi)
04338 mlo = mhi = multadd(mhi, 10, 0);
04339 else {
04340 mlo = multadd(mlo, 10, 0);
04341 mhi = multadd(mhi, 10, 0);
04342 }
04343 }
04344 }
04345 else
04346 for(i = 1;; i++) {
04347 *s++ = dig = quorem(b,S) + '0';
04348 if (!b->x[0] && b->wds <= 1) {
04349 #ifdef SET_INEXACT
04350 inexact = 0;
04351 #endif
04352 goto ret;
04353 }
04354 if (i >= ilim)
04355 break;
04356 b = multadd(b, 10, 0);
04357 }
04358
04359
04360
04361 #ifdef Honor_FLT_ROUNDS
04362 switch(Rounding) {
04363 case 0: goto trimzeros;
04364 case 2: goto roundoff;
04365 }
04366 #endif
04367 b = lshift(b, 1);
04368 j = cmp(b, S);
04369 #ifdef ROUND_BIASED
04370 if (j >= 0)
04371 #else
04372 if (j > 0 || (j == 0 && dig & 1))
04373 #endif
04374 {
04375 roundoff:
04376 while(*--s == '9')
04377 if (s == s0) {
04378 k++;
04379 *s++ = '1';
04380 goto ret;
04381 }
04382 ++*s++;
04383 }
04384 else {
04385 #ifdef Honor_FLT_ROUNDS
04386 trimzeros:
04387 #endif
04388 while(*--s == '0');
04389 s++;
04390 }
04391 ret:
04392 Bfree(S);
04393 if (mhi) {
04394 if (mlo && mlo != mhi)
04395 Bfree(mlo);
04396 Bfree(mhi);
04397 }
04398 ret1:
04399 #ifdef SET_INEXACT
04400 if (inexact) {
04401 if (!oldinexact) {
04402 word0(&u) = Exp_1 + (70 << Exp_shift);
04403 word1(&u) = 0;
04404 dval(&u) += 1.;
04405 }
04406 }
04407 else if (!oldinexact)
04408 clear_inexact();
04409 #endif
04410 Bfree(b);
04411 *s = 0;
04412 *decpt = k + 1;
04413 if (rve)
04414 *rve = s;
04415 return s0;
04416 }
04417 #ifdef __cplusplus
04418 }
04419 #endif