diff options
author | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-04 20:05:30 +0000 |
---|---|---|
committer | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-04 20:05:30 +0000 |
commit | 43c0748ef6398de7c3ee1ea1a7915709047e3907 (patch) | |
tree | a71ab2ed6f13589e6cd114e9e800fc3aa030e86b | |
parent | 6a0629b407575b89cac13f3351e41ae00816f154 (diff) | |
download | chromium_src-43c0748ef6398de7c3ee1ea1a7915709047e3907.zip chromium_src-43c0748ef6398de7c3ee1ea1a7915709047e3907.tar.gz chromium_src-43c0748ef6398de7c3ee1ea1a7915709047e3907.tar.bz2 |
Revert "Merge latest changes from http://www.netlib.org/fp/dtoa.c into dtoa.cc"
This reverts commit r15232.
Review URL: http://codereview.chromium.org/99366
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15233 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/third_party/dmg_fp/README.chromium | 1 | ||||
-rw-r--r-- | base/third_party/dmg_fp/dtoa.cc | 1857 | ||||
-rw-r--r-- | base/third_party/dmg_fp/gcc_warnings.patch | 202 |
3 files changed, 670 insertions, 1390 deletions
diff --git a/base/third_party/dmg_fp/README.chromium b/base/third_party/dmg_fp/README.chromium index 4f75398..c57333b 100644 --- a/base/third_party/dmg_fp/README.chromium +++ b/base/third_party/dmg_fp/README.chromium @@ -10,6 +10,5 @@ List of changes made to original code: - renamed .c files to .cc - added dmg_fp.h header - added #define IEEE_8087 to dtoa.cc - - added #define NO_HEX_FP to dtoa.cc - made some minor changes to allow clean compilation under g++ -Wall, see gcc_warnings.patch. diff --git a/base/third_party/dmg_fp/dtoa.cc b/base/third_party/dmg_fp/dtoa.cc index 6ab2aef..ba49857 100644 --- a/base/third_party/dmg_fp/dtoa.cc +++ b/base/third_party/dmg_fp/dtoa.cc @@ -103,12 +103,7 @@ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) * if memory is available and otherwise does something you deem * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. Similarly, if you - * want something other than the system's free() to be called to - * recycle memory acquired from MALLOC, #define FREE to be the - * name of the alternate routine. (FREE or free is only called in - * pathological cases, e.g., in a dtoa call after a dtoa return in - * mode 3 with thousands of digits requested.) + * directly -- and assumed always to succeed. * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making * memory allocations from a private pool of memory when possible. * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, @@ -152,6 +147,11 @@ * floating-point numbers and flushes underflows to zero rather * than implementing gradual underflow, then you must also #define * Sudden_Underflow. + * #define YES_ALIAS to permit aliasing certain double values with + * arrays of ULongs. This leads to slightly better code with + * some compilers and was always used prior to 19990916, but it + * is not strictly legal and can cause trouble with aggressively + * optimizing compilers (e.g., gcc 2.95.1 under -O2). * #define USE_LOCALE to use the current locale's decimal_point value. * #define SET_INEXACT if IEEE arithmetic is being used and extra * computation should be done to set the inexact flag when the @@ -169,18 +169,13 @@ * inexact or when it is a numeric value rounded to +-infinity). * #define NO_ERRNO if strtod should not assign errno = ERANGE when * the result overflows to +-Infinity or underflows to 0. - * #define NO_HEX_FP to omit recognition of hexadecimal floating-point - * values by strtod. - * #define NO_STRTOD_BIGCOMP (on IEEE-arithmetic systems only for now) - * to disable logic for "fast" testing of very long input strings - * to strtod. This testing proceeds by initially truncating the - * input string, then if necessary comparing the whole string with - * a decimal expansion to decide close cases. This logic is only - * used for input more than STRTOD_DIGLIM digits long (default 40). */ #define IEEE_8087 -#define NO_HEX_FP +#if defined(__GNUC__) +// Make gcc 4.3+ warnings about parentheses non-fatal warnings. +#pragma GCC diagnostic warning "-Wparentheses" +#endif #ifndef Long #define Long long @@ -201,12 +196,6 @@ typedef unsigned Long ULong; #include "locale.h" #endif -#ifdef Honor_FLT_ROUNDS -#ifndef Trust_FLT_ROUNDS -#include <fenv.h> -#endif -#endif - #ifdef MALLOC #ifdef KR_headers extern char *MALLOC(); @@ -241,7 +230,6 @@ static double private_mem[PRIVATE_mem], *pmem_next = private_mem; #endif #else #undef INFNAN_CHECK -#define NO_STRTOD_BIGCOMP #endif #include "errno.h" @@ -299,23 +287,24 @@ Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. typedef union { double d; ULong L[2]; } U; +#ifdef YES_ALIAS +#define dval(x) x #ifdef IEEE_8087 -#define word0(x) (x)->L[1] -#define word1(x) (x)->L[0] +#define word0(x) ((ULong *)&x)[1] +#define word1(x) ((ULong *)&x)[0] #else -#define word0(x) (x)->L[0] -#define word1(x) (x)->L[1] +#define word0(x) ((ULong *)&x)[0] +#define word1(x) ((ULong *)&x)[1] #endif -#define dval(x) (x)->d - -#ifndef STRTOD_DIGLIM -#define STRTOD_DIGLIM 40 -#endif - -#ifdef DIGLIM_DEBUG -extern int strtod_diglim; #else -#define strtod_diglim STRTOD_DIGLIM +#ifdef IEEE_8087 +#define word0(x) ((U*)&x)->L[1] +#define word1(x) ((U*)&x)->L[0] +#else +#define word0(x) ((U*)&x)->L[0] +#define word1(x) ((U*)&x)->L[1] +#endif +#define dval(x) ((U*)&x)->d #endif /* The following definition of Storeinc is appropriate for MIPS processors. @@ -343,9 +332,7 @@ extern int strtod_diglim; #define Exp_msk11 0x100000 #define Exp_mask 0x7ff00000 #define P 53 -#define Nbits 53 #define Bias 1023 -#define Emax 1023 #define Emin (-1022) #define Exp_1 0x3ff00000 #define Exp_11 0x3ff00000 @@ -400,10 +387,7 @@ extern int strtod_diglim; #define Exp_msk11 0x1000000 #define Exp_mask 0x7f000000 #define P 14 -#define Nbits 56 #define Bias 65 -#define Emax 248 -#define Emin (-260) #define Exp_1 0x41000000 #define Exp_11 0x41000000 #define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ @@ -429,10 +413,7 @@ extern int strtod_diglim; #define Exp_msk11 0x800000 #define Exp_mask 0x7f80 #define P 56 -#define Nbits 56 #define Bias 129 -#define Emax 126 -#define Emin (-129) #define Exp_1 0x40800000 #define Exp_11 0x4080 #define Ebits 8 @@ -476,10 +457,6 @@ extern double rnd_prod(double, double), rnd_quot(double, double); #define Pack_32 #endif -typedef struct BCinfo BCinfo; - struct -BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; }; - #ifdef KR_headers #define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff) #else @@ -510,7 +487,7 @@ BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflc #define FREE_DTOA_LOCK(n) /*nothing*/ #endif -#define Kmax 7 +#define Kmax 15 double strtod(const char *s00, char **se); char *dtoa(double d, int mode, int ndigits, @@ -542,10 +519,9 @@ Balloc #endif ACQUIRE_DTOA_LOCK(0); - /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ - /* but this case seems very unlikely. */ - if (k <= Kmax && (rv = freelist[k])) + if ((rv = freelist[k])) { freelist[k] = rv->next; + } else { x = 1 << k; #ifdef Omit_Private_Memory @@ -553,7 +529,7 @@ Balloc #else len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { + if (pmem_next - private_mem + len <= PRIVATE_mem) { rv = (Bigint*)pmem_next; pmem_next += len; } @@ -577,18 +553,10 @@ Bfree #endif { if (v) { - if (v->k > Kmax) -#ifdef FREE - FREE((void*)v); -#else - free((void*)v); -#endif - else { - ACQUIRE_DTOA_LOCK(0); - v->next = freelist[v->k]; - freelist[v->k] = v; - FREE_DTOA_LOCK(0); - } + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); } } @@ -655,9 +623,9 @@ multadd static Bigint * s2b #ifdef KR_headers - (s, nd0, nd, y9, dplen) CONST char *s; int nd0, nd, dplen; ULong y9; + (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; #else - (CONST char *s, int nd0, int nd, ULong y9, int dplen) + (CONST char *s, int nd0, int nd, ULong y9) #endif { Bigint *b; @@ -681,10 +649,10 @@ s2b s += 9; do b = multadd(b, 10, *s++ - '0'); while(++i < nd0); - s += dplen; + s++; } else - s += dplen + 9; + s += 10; for(; i < nd; i++) b = multadd(b, 10, *s++ - '0'); return b; @@ -693,12 +661,12 @@ s2b static int hi0bits #ifdef KR_headers - (x) ULong x; + (x) register ULong x; #else - (ULong x) + (register ULong x) #endif { - int k = 0; + register int k = 0; if (!(x & 0xffff0000)) { k = 16; @@ -732,8 +700,8 @@ lo0bits (ULong *y) #endif { - int k; - ULong x = *y; + register int k; + register ULong x = *y; if (x & 7) { if (x & 1) @@ -1148,13 +1116,13 @@ diff static double ulp #ifdef KR_headers - (x) U *x; + (x) double x; #else - (U *x) + (double x) #endif { - Long L; - U u; + register Long L; + double a; L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; #ifndef Avoid_Underflow @@ -1165,26 +1133,26 @@ ulp #ifdef IBM L |= Exp_msk1 >> 4; #endif - word0(&u) = L; - word1(&u) = 0; + word0(a) = L; + word1(a) = 0; #ifndef Avoid_Underflow #ifndef Sudden_Underflow } else { L = -L >> Exp_shift; if (L < Exp_shift) { - word0(&u) = 0x80000 >> L; - word1(&u) = 0; + word0(a) = 0x80000 >> L; + word1(a) = 0; } else { - word0(&u) = 0; + word0(a) = 0; L -= Exp_shift; - word1(&u) = L >= 31 ? 1 : 1 << 31 - L; + word1(a) = L >= 31 ? 1 : 1 << 31 - L; } } #endif #endif - return dval(&u); + return dval(a); } static double @@ -1197,12 +1165,12 @@ b2d { ULong *xa, *xa0, w, y, z; int k; - U d; + double d; #ifdef VAX ULong d0, d1; #else -#define d0 word0(&d) -#define d1 word1(&d) +#define d0 word0(d) +#define d1 word1(d) #endif xa0 = a->x; @@ -1215,16 +1183,16 @@ b2d *e = 32 - k; #ifdef Pack_32 if (k < Ebits) { - d0 = Exp_1 | y >> (Ebits - k); + d0 = Exp_1 | y >> Ebits - k; w = xa > xa0 ? *--xa : 0; - d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); + d1 = y << (32-Ebits) + k | w >> Ebits - k; goto ret_d; } z = xa > xa0 ? *--xa : 0; if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> (32 - k); + d0 = Exp_1 | y << k | z >> 32 - k; y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> (32 - k); + d1 = z << k | y >> 32 - k; } else { d0 = Exp_1 | y; @@ -1248,21 +1216,21 @@ b2d #endif ret_d: #ifdef VAX - word0(&d) = d0 >> 16 | d0 << 16; - word1(&d) = d1 >> 16 | d1 << 16; + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; #else #undef d0 #undef d1 #endif - return dval(&d); + return dval(d); } static Bigint * d2b #ifdef KR_headers - (d, e, bits) U *d; int *e, *bits; + (d, e, bits) double d; int *e, *bits; #else - (U *d, int *e, int *bits) + (double d, int *e, int *bits) #endif { Bigint *b; @@ -1301,7 +1269,7 @@ d2b #ifdef Pack_32 if ((y = d1)) { if ((k = lo0bits(&y))) { - x[0] = y | z << (32 - k); + x[0] = y | z << 32 - k; z >>= k; } else @@ -1312,6 +1280,10 @@ d2b b->wds = (x[1] = z) ? 2 : 1; } else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif k = lo0bits(&z); x[0] = z; #ifndef Sudden_Underflow @@ -1399,11 +1371,11 @@ ratio (Bigint *a, Bigint *b) #endif { - U da, db; + double da, db; int k, ka, kb; - dval(&da) = b2d(a, &ka); - dval(&db) = b2d(b, &kb); + dval(da) = b2d(a, &ka); + dval(db) = b2d(b, &kb); #ifdef Pack_32 k = ka - kb + 32*(a->wds - b->wds); #else @@ -1411,25 +1383,25 @@ ratio #endif #ifdef IBM if (k > 0) { - word0(&da) += (k >> 2)*Exp_msk1; + word0(da) += (k >> 2)*Exp_msk1; if (k &= 3) - dval(&da) *= 1 << k; + dval(da) *= 1 << k; } else { k = -k; - word0(&db) += (k >> 2)*Exp_msk1; + word0(db) += (k >> 2)*Exp_msk1; if (k &= 3) - dval(&db) *= 1 << k; + dval(db) *= 1 << k; } #else if (k > 0) - word0(&da) += k*Exp_msk1; + word0(da) += k*Exp_msk1; else { k = -k; - word0(&db) += k*Exp_msk1; + word0(db) += k*Exp_msk1; } #endif - return dval(&da) / dval(&db); + return dval(da) / dval(db); } static CONST double @@ -1469,48 +1441,6 @@ static CONST double tinytens[] = { 1e-16, 1e-32 }; #endif #endif -#undef Need_Hexdig -#ifdef INFNAN_CHECK -#ifndef No_Hex_NaN -#define Need_Hexdig -#endif -#endif - -#ifndef Need_Hexdig -#ifndef NO_HEX_FP -#define Need_Hexdig -#endif -#endif - -#ifdef Need_Hexdig /*{*/ -static unsigned char hexdig[256]; - - static void -#ifdef KR_headers -htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; -#else -htinit(unsigned char *h, unsigned char *s, int inc) -#endif -{ - int i, j; - for(i = 0; (j = s[i]) !=0; i++) - h[j] = i + inc; - } - - static void -#ifdef KR_headers -hexdig_init() -#else -hexdig_init(void) -#endif -{ -#define USC (unsigned char *) - htinit(hexdig, USC "0123456789", 0x10); - htinit(hexdig, USC "abcdef", 0x10 + 10); - htinit(hexdig, USC "ABCDEF", 0x10 + 10); - } -#endif /* } Need_Hexdig */ - #ifdef INFNAN_CHECK #ifndef NAN_WORD0 @@ -1546,17 +1476,15 @@ match static void hexnan #ifdef KR_headers - (rvp, sp) U *rvp; CONST char **sp; + (rvp, sp) double *rvp; CONST char **sp; #else - (U *rvp, CONST char **sp) + (double *rvp, CONST char **sp) #endif { ULong c, x[2]; CONST char *s; - int c1, havedig, udx0, xshift; + int havedig, udx0, xshift; - if (!hexdig['0']) - hexdig_init(); x[0] = x[1] = 0; havedig = xshift = 0; udx0 = 1; @@ -1567,8 +1495,12 @@ hexnan if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')) s += 2; while((c = *(CONST unsigned char*)++s)) { - if ((c1 = hexdig[c])) - c = c1 & 0xf; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'a' && c <= 'f') + c += 10 - 'a'; + else if (c >= 'A' && c <= 'F') + c += 10 - 'A'; else if (c <= ' ') { if (udx0 && havedig) { udx0 = 0; @@ -1605,818 +1537,13 @@ hexnan x[1] = (x[1] << 4) | c; } if ((x[0] &= 0xfffff) || x[1]) { - word0(rvp) = Exp_mask | x[0]; - word1(rvp) = x[1]; + word0(*rvp) = Exp_mask | x[0]; + word1(*rvp) = x[1]; } } #endif /*No_Hex_NaN*/ #endif /* INFNAN_CHECK */ -#ifdef Pack_32 -#define ULbits 32 -#define kshift 5 -#define kmask 31 -#else -#define ULbits 16 -#define kshift 4 -#define kmask 15 -#endif -#ifndef NO_HEX_FP /*{*/ - - static void -#ifdef KR_headers -rshift(b, k) Bigint *b; int k; -#else -rshift(Bigint *b, int k) -#endif -{ - ULong *x, *x1, *xe, y; - int n; - - x = x1 = b->x; - n = k >> kshift; - if (n < b->wds) { - xe = x + b->wds; - x += n; - if (k &= kmask) { - n = 32 - k; - y = *x++ >> k; - while(x < xe) { - *x1++ = (y | (*x << n)) & 0xffffffff; - y = *x++ >> k; - } - if ((*x1 = y) !=0) - x1++; - } - else - while(x < xe) - *x1++ = *x++; - } - if ((b->wds = x1 - b->x) == 0) - b->x[0] = 0; - } - - static ULong -#ifdef KR_headers -any_on(b, k) Bigint *b; int k; -#else -any_on(Bigint *b, int k) -#endif -{ - int n, nwds; - ULong *x, *x0, x1, x2; - - x = b->x; - nwds = b->wds; - n = k >> kshift; - if (n > nwds) - n = nwds; - else if (n < nwds && (k &= kmask)) { - x1 = x2 = x[n]; - x1 >>= k; - x1 <<= k; - if (x1 != x2) - return 1; - } - x0 = x; - x += n; - while(x > x0) - if (*--x) - return 1; - return 0; - } - -enum { /* rounding values: same as FLT_ROUNDS */ - Round_zero = 0, - Round_near = 1, - Round_up = 2, - Round_down = 3 - }; - - static Bigint * -#ifdef KR_headers -increment(b) Bigint *b; -#else -increment(Bigint *b) -#endif -{ - ULong *x, *xe; - Bigint *b1; - - x = b->x; - xe = x + b->wds; - do { - if (*x < (ULong)0xffffffffL) { - ++*x; - return b; - } - *x++ = 0; - } while(x < xe); - { - if (b->wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1,b); - Bfree(b); - b = b1; - } - b->x[b->wds++] = 1; - } - return b; - } - - void -#ifdef KR_headers -gethex(sp, rvp, rounding, sign) - CONST char **sp; U *rvp; int rounding, sign; -#else -gethex( CONST char **sp, U *rvp, int rounding, int sign) -#endif -{ - Bigint *b; - CONST unsigned char *decpt, *s0, *s, *s1; - Long e, e1; - ULong L, lostbits, *x; - int big, denorm, esign, havedig, k, n, nbits, up, zret; -#ifdef IBM - int j; -#endif - enum { -#ifdef IEEE_Arith /*{{*/ - emax = 0x7fe - Bias - P + 1, - emin = Emin - P + 1 -#else /*}{*/ - emin = Emin - P, -#ifdef VAX - emax = 0x7ff - Bias - P + 1 -#endif -#ifdef IBM - emax = 0x7f - Bias - P -#endif -#endif /*}}*/ - }; -#ifdef USE_LOCALE - int i; -#ifdef NO_LOCALE_CACHE - const unsigned char *decimalpoint = (unsigned char*) - localeconv()->decimal_point; -#else - const unsigned char *decimalpoint; - static unsigned char *decimalpoint_cache; - if (!(s0 = decimalpoint_cache)) { - s0 = (unsigned char*)localeconv()->decimal_point; - if ((decimalpoint_cache = (unsigned char*) - MALLOC(strlen((CONST char*)s0) + 1))) { - strcpy((char*)decimalpoint_cache, (CONST char*)s0); - s0 = decimalpoint_cache; - } - } - decimalpoint = s0; -#endif -#endif - - if (!hexdig['0']) - hexdig_init(); - havedig = 0; - s0 = *(CONST unsigned char **)sp + 2; - while(s0[havedig] == '0') - havedig++; - s0 += havedig; - s = s0; - decpt = 0; - zret = 0; - e = 0; - if (hexdig[*s]) - havedig++; - else { - zret = 1; -#ifdef USE_LOCALE - for(i = 0; decimalpoint[i]; ++i) { - if (s[i] != decimalpoint[i]) - goto pcheck; - } - decpt = s += i; -#else - if (*s != '.') - goto pcheck; - decpt = ++s; -#endif - if (!hexdig[*s]) - goto pcheck; - while(*s == '0') - s++; - if (hexdig[*s]) - zret = 0; - havedig = 1; - s0 = s; - } - while(hexdig[*s]) - s++; -#ifdef USE_LOCALE - if (*s == *decimalpoint && !decpt) { - for(i = 1; decimalpoint[i]; ++i) { - if (s[i] != decimalpoint[i]) - goto pcheck; - } - decpt = s += i; -#else - if (*s == '.' && !decpt) { - decpt = ++s; -#endif - while(hexdig[*s]) - s++; - }/*}*/ - if (decpt) - e = -(((Long)(s-decpt)) << 2); - pcheck: - s1 = s; - big = esign = 0; - switch(*s) { - case 'p': - case 'P': - switch(*++s) { - case '-': - esign = 1; - /* no break */ - case '+': - s++; - } - if ((n = hexdig[*s]) == 0 || n > 0x19) { - s = s1; - break; - } - e1 = n - 0x10; - while((n = hexdig[*++s]) !=0 && n <= 0x19) { - if (e1 & 0xf8000000) - big = 1; - e1 = 10*e1 + n - 0x10; - } - if (esign) - e1 = -e1; - e += e1; - } - *sp = (char*)s; - if (!havedig) - *sp = (char*)s0 - 1; - if (zret) - goto retz1; - if (big) { - if (esign) { -#ifdef IEEE_Arith - switch(rounding) { - case Round_up: - if (sign) - break; - goto ret_tiny; - case Round_down: - if (!sign) - break; - goto ret_tiny; - } -#endif - goto retz; -#ifdef IEEE_Arith - ret_tiny: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - word0(rvp) = 0; - word1(rvp) = 1; - return; -#endif /* IEEE_Arith */ - } - switch(rounding) { - case Round_near: - goto ovfl1; - case Round_up: - if (!sign) - goto ovfl1; - goto ret_big; - case Round_down: - if (sign) - goto ovfl1; - goto ret_big; - } - ret_big: - word0(rvp) = Big0; - word1(rvp) = Big1; - return; - } - n = s1 - s0 - 1; - for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) - k++; - b = Balloc(k); - x = b->x; - n = 0; - L = 0; -#ifdef USE_LOCALE - for(i = 0; decimalpoint[i+1]; ++i); -#endif - while(s1 > s0) { -#ifdef USE_LOCALE - if (*--s1 == decimalpoint[i]) { - s1 -= i; - continue; - } -#else - if (*--s1 == '.') - continue; -#endif - if (n == ULbits) { - *x++ = L; - L = 0; - n = 0; - } - L |= (hexdig[*s1] & 0x0f) << n; - n += 4; - } - *x++ = L; - b->wds = n = x - b->x; - n = ULbits*n - hi0bits(L); - nbits = Nbits; - lostbits = 0; - x = b->x; - if (n > nbits) { - n -= nbits; - if (any_on(b,n)) { - lostbits = 1; - k = n - 1; - if (x[k>>kshift] & 1 << (k & kmask)) { - lostbits = 2; - if (k > 0 && any_on(b,k)) - lostbits = 3; - } - } - rshift(b, n); - e += n; - } - else if (n < nbits) { - n = nbits - n; - b = lshift(b, n); - e -= n; - x = b->x; - } - if (e > Emax) { - ovfl: - Bfree(b); - ovfl1: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - word0(rvp) = Exp_mask; - word1(rvp) = 0; - return; - } - denorm = 0; - if (e < emin) { - denorm = 1; - n = emin - e; - if (n >= nbits) { -#ifdef IEEE_Arith /*{*/ - switch (rounding) { - case Round_near: - if (n == nbits && (n < 2 || any_on(b,n-1))) - goto ret_tiny; - break; - case Round_up: - if (!sign) - goto ret_tiny; - break; - case Round_down: - if (sign) - goto ret_tiny; - } -#endif /* } IEEE_Arith */ - Bfree(b); - retz: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - retz1: - rvp->d = 0.; - return; - } - k = n - 1; - if (lostbits) - lostbits = 1; - else if (k > 0) - lostbits = any_on(b,k); - if (x[k>>kshift] & 1 << (k & kmask)) - lostbits |= 2; - nbits -= n; - rshift(b,n); - e = emin; - } - if (lostbits) { - up = 0; - switch(rounding) { - case Round_zero: - break; - case Round_near: - if (lostbits & 2 - && (lostbits & 1) | (x[0] & 1)) - up = 1; - break; - case Round_up: - up = 1 - sign; - break; - case Round_down: - up = sign; - } - if (up) { - k = b->wds; - b = increment(b); - x = b->x; - if (denorm) { -#if 0 - if (nbits == Nbits - 1 - && x[nbits >> kshift] & 1 << (nbits & kmask)) - denorm = 0; /* not currently used */ -#endif - } - else if (b->wds > k - || ((n = nbits & kmask) !=0 - && hi0bits(x[k-1]) < 32-n)) { - rshift(b,1); - if (++e > Emax) - goto ovfl; - } - } - } -#ifdef IEEE_Arith - if (denorm) - word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0; - else - word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20); - word1(rvp) = b->x[0]; -#endif -#ifdef IBM - if ((j = e & 3)) { - k = b->x[0] & ((1 << j) - 1); - rshift(b,j); - if (k) { - switch(rounding) { - case Round_up: - if (!sign) - increment(b); - break; - case Round_down: - if (sign) - increment(b); - break; - case Round_near: - j = 1 << (j-1); - if (k & j && ((k & (j-1)) | lostbits)) - increment(b); - } - } - } - e >>= 2; - word0(rvp) = b->x[1] | ((e + 65 + 13) << 24); - word1(rvp) = b->x[0]; -#endif -#ifdef VAX - /* The next two lines ignore swap of low- and high-order 2 bytes. */ - /* word0(rvp) = (b->x[1] & ~0x800000) | ((e + 129 + 55) << 23); */ - /* word1(rvp) = b->x[0]; */ - word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16); - word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16); -#endif - Bfree(b); - } -#endif /*}!NO_HEX_FP*/ - - static int -#ifdef KR_headers -dshift(b, p2) Bigint *b; int p2; -#else -dshift(Bigint *b, int p2) -#endif -{ - int rv = hi0bits(b->x[b->wds-1]) - 4; - if (p2 > 0) - rv -= p2; - return rv & kmask; - } - - static int -quorem -#ifdef KR_headers - (b, S) Bigint *b, *S; -#else - (Bigint *b, Bigint *S) -#endif -{ - int n; - ULong *bx, *bxe, q, *sx, *sxe; -#ifdef ULLong - ULLong borrow, carry, y, ys; -#else - ULong borrow, carry, y, ys; -#ifdef Pack_32 - ULong si, z, zs; -#endif -#endif - - n = S->wds; -#ifdef DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ -#ifdef DEBUG - /*debug*/ if (q > 9) - /*debug*/ Bug("oversized quotient in quorem"); -#endif - if (q) { - borrow = 0; - carry = 0; - do { -#ifdef ULLong - ys = *sx++ * (ULLong)q + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { -#ifdef ULLong - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; - } - -#ifndef NO_STRTOD_BIGCOMP - - static void -bigcomp -#ifdef KR_headers - (rv, s0, bc) - U *rv; CONST char *s0; BCinfo *bc; -#else - (U *rv, CONST char *s0, BCinfo *bc) -#endif -{ - Bigint *b, *d; - int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; - - dsign = bc->dsign; - nd = bc->nd; - nd0 = bc->nd0; - p5 = nd + bc->e0 - 1; - speccase = 0; -#ifndef Sudden_Underflow - if (rv->d == 0.) { /* special case: value near underflow-to-zero */ - /* threshold was rounded to zero */ - b = i2b(1); - p2 = Emin - P + 1; - bbits = 1; -#ifdef Avoid_Underflow - word0(rv) = (P+2) << Exp_shift; -#else - word1(rv) = 1; -#endif - i = 0; -#ifdef Honor_FLT_ROUNDS - if (bc->rounding == 1) -#endif - { - speccase = 1; - --p2; - dsign = 0; - goto have_i; - } - } - else -#endif - b = d2b(rv, &p2, &bbits); -#ifdef Avoid_Underflow - p2 -= bc->scale; -#endif - /* floor(log2(rv)) == bbits - 1 + p2 */ - /* Check for denormal case. */ - i = P - bbits; - if (i > (j = P - Emin - 1 + p2)) { -#ifdef Sudden_Underflow - Bfree(b); - b = i2b(1); - p2 = Emin; - i = P - 1; -#ifdef Avoid_Underflow - word0(rv) = (1 + bc->scale) << Exp_shift; -#else - word0(rv) = Exp_msk1; -#endif - word1(rv) = 0; -#else - i = j; -#endif - } -#ifdef Honor_FLT_ROUNDS - if (bc->rounding != 1) { - if (i > 0) - b = lshift(b, i); - if (dsign) - b = increment(b); - } - else -#endif - { - b = lshift(b, ++i); - b->x[0] |= 1; - } -#ifndef Sudden_Underflow - have_i: -#endif - p2 -= p5 + i; - d = i2b(1); - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - */ - if (p5 > 0) - d = pow5mult(d, p5); - else if (p5 < 0) - b = pow5mult(b, -p5); - if (p2 > 0) { - b2 = p2; - d2 = 0; - } - else { - b2 = 0; - d2 = -p2; - } - i = dshift(d, d2); - if ((b2 += i) > 0) - b = lshift(b, b2); - if ((d2 += i) > 0) - d = lshift(d, d2); - - /* Now b/d = exactly half-way between the two floating-point values */ - /* on either side of the input string. Compute first digit of b/d. */ - - if (!(dig = quorem(b,d))) { - b = multadd(b, 10, 0); /* very unlikely */ - dig = quorem(b,d); - } - - /* Compare b/d with s0 */ - - for(i = 0; i < nd0; ) { - if ((dd = s0[i++] - '0' - dig)) - goto ret; - if (!b->x[0] && b->wds == 1) { - if (i < nd) - dd = 1; - goto ret; - } - b = multadd(b, 10, 0); - dig = quorem(b,d); - } - for(j = bc->dp1; i++ < nd;) { - if ((dd = s0[j++] - '0' - dig)) - goto ret; - if (!b->x[0] && b->wds == 1) { - if (i < nd) - dd = 1; - goto ret; - } - b = multadd(b, 10, 0); - dig = quorem(b,d); - } - if (b->x[0] || b->wds > 1) - dd = -1; - ret: - Bfree(b); - Bfree(d); -#ifdef Honor_FLT_ROUNDS - if (bc->rounding != 1) { - if (dd < 0) { - if (bc->rounding == 0) { - if (!dsign) - goto retlow1; - } - else if (dsign) - goto rethi1; - } - else if (dd > 0) { - if (bc->rounding == 0) { - if (dsign) - goto rethi1; - goto ret1; - } - if (!dsign) - goto rethi1; - dval(rv) += 2.*ulp(rv); - } - else { - bc->inexact = 0; - if (dsign) - goto rethi1; - } - } - else -#endif - if (speccase) { - if (dd <= 0) - rv->d = 0.; - } - else if (dd < 0) { - if (!dsign) /* does not happen for round-near */ -retlow1: - dval(rv) -= ulp(rv); - } - else if (dd > 0) { - if (dsign) { - rethi1: - dval(rv) += ulp(rv); - } - } - else { - /* Exact half-way case: apply round-even rule. */ - if (word1(rv) & 1) { - if (dsign) - goto rethi1; - goto retlow1; - } - } - -#ifdef Honor_FLT_ROUNDS - ret1: -#endif - return; - } -#endif /* NO_STRTOD_BIGCOMP */ - double strtod #ifdef KR_headers @@ -2425,27 +1552,29 @@ strtod (CONST char *s00, char **se) #endif { - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; - int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; +#ifdef Avoid_Underflow + int scale; +#endif + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; - double aadj, aadj1; + double aadj, aadj1, adj, rv, rv0; Long L; - U aadj2, adj, rv, rv0; ULong y, z; - BCinfo bc; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; #ifdef SET_INEXACT - int oldinexact; + int inexact, oldinexact; #endif #ifdef Honor_FLT_ROUNDS /*{*/ + int Rounding; #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ - bc.rounding = Flt_Rounds; + Rounding = Flt_Rounds; #else /*}{*/ - bc.rounding = 1; + Rounding = 1; switch(fegetround()) { - case FE_TOWARDZERO: bc.rounding = 0; break; - case FE_UPWARD: bc.rounding = 2; break; - case FE_DOWNWARD: bc.rounding = 3; + case FE_TOWARDZERO: Rounding = 0; break; + case FE_UPWARD: Rounding = 2; break; + case FE_DOWNWARD: Rounding = 3; } #endif /*}}*/ #endif /*}*/ @@ -2453,8 +1582,8 @@ strtod CONST char *s2; #endif - sign = nz0 = nz = bc.dplen = bc.uflchk = 0; - dval(&rv) = 0.; + sign = nz0 = nz = 0; + dval(rv) = 0.; for(s = s00;;s++) switch(*s) { case '-': sign = 1; @@ -2477,18 +1606,6 @@ strtod } break2: if (*s == '0') { -#ifndef NO_HEX_FP /*{*/ - switch(s[1]) { - case 'x': - case 'X': -#ifdef Honor_FLT_ROUNDS - gethex(&s, &rv, bc.rounding, sign); -#else - gethex(&s, &rv, 1, sign); -#endif - goto ret; - } -#endif /*}*/ nz0 = 1; while(*++s == '0') ; if (!*s) @@ -2502,7 +1619,6 @@ strtod else if (nd < 16) z = 10*z + c - '0'; nd0 = nd; - bc.dp0 = bc.dp1 = s - s0; #ifdef USE_LOCALE s1 = localeconv()->decimal_point; if (c == *s1) { @@ -2524,8 +1640,6 @@ strtod #endif if (c == '.') { c = *++s; - bc.dp1 = s - s0; - bc.dplen = bc.dp1 - bc.dp0; if (!nd) { for(; c == '0'; c = *++s) nz++; @@ -2597,24 +1711,23 @@ strtod if (!nz && !nz0) { #ifdef INFNAN_CHECK /* Check for Nan and Infinity */ - if (!bc.dplen) - switch(c) { + switch(c) { case 'i': case 'I': if (match(&s,"nf")) { --s; if (!match(&s,"inity")) ++s; - word0(&rv) = 0x7ff00000; - word1(&rv) = 0; + word0(rv) = 0x7ff00000; + word1(rv) = 0; goto ret; } break; case 'n': case 'N': if (match(&s, "an")) { - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; #ifndef No_Hex_NaN if (*s == '(') /*)*/ hexnan(&rv, &s); @@ -2629,7 +1742,7 @@ strtod } goto ret; } - bc.e0 = e1 = e -= nf; + e1 = e -= nf; /* Now we have nd0 digits, starting at s0, followed by a * decimal point, followed by nd-nd0 digits. The number we're @@ -2639,13 +1752,13 @@ strtod if (!nd0) nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(&rv) = y; + dval(rv) = y; if (k > 9) { #ifdef SET_INEXACT if (k > DBL_DIG) oldinexact = get_inexact(); #endif - dval(&rv) = tens[k - 9] * dval(&rv) + z; + dval(rv) = tens[k - 9] * dval(rv) + z; } bd0 = 0; if (nd <= DBL_DIG @@ -2665,11 +1778,11 @@ strtod #ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv.d = -rv.d; + rv = -rv; sign = 0; } #endif - /* rv = */ rounded_product(dval(&rv), tens[e]); + /* rv = */ rounded_product(dval(rv), tens[e]); goto ret; #endif } @@ -2681,25 +1794,25 @@ strtod #ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv.d = -rv.d; + rv = -rv; sign = 0; } #endif e -= i; - dval(&rv) *= tens[i]; + dval(rv) *= tens[i]; #ifdef VAX /* VAX exponent range is so narrow we must * worry about overflow here... */ vax_ovfl_check: - word0(&rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(&rv), tens[e]); - if ((word0(&rv) & Exp_mask) + word0(rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(rv), tens[e]); + if ((word0(rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) goto ovfl; - word0(&rv) += P*Exp_msk1; + word0(rv) += P*Exp_msk1; #else - /* rv = */ rounded_product(dval(&rv), tens[e]); + /* rv = */ rounded_product(dval(rv), tens[e]); #endif goto ret; } @@ -2709,11 +1822,11 @@ strtod #ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv.d = -rv.d; + rv = -rv; sign = 0; } #endif - /* rv = */ rounded_quotient(dval(&rv), tens[-e]); + /* rv = */ rounded_quotient(dval(rv), tens[-e]); goto ret; } #endif @@ -2722,20 +1835,20 @@ strtod #ifdef IEEE_Arith #ifdef SET_INEXACT - bc.inexact = 1; + inexact = 1; if (k <= DBL_DIG) oldinexact = get_inexact(); #endif #ifdef Avoid_Underflow - bc.scale = 0; + scale = 0; #endif #ifdef Honor_FLT_ROUNDS - if (bc.rounding >= 2) { + if (Rounding >= 2) { if (sign) - bc.rounding = bc.rounding == 2 ? 0 : 2; + Rounding = Rounding == 2 ? 0 : 2; else - if (bc.rounding != 2) - bc.rounding = 0; + if (Rounding != 2) + Rounding = 0; } #endif #endif /*IEEE_Arith*/ @@ -2744,7 +1857,7 @@ strtod if (e1 > 0) { if ((i = e1 & 15)) - dval(&rv) *= tens[i]; + dval(rv) *= tens[i]; if (e1 &= ~15) { if (e1 > DBL_MAX_10_EXP) { ovfl: @@ -2754,99 +1867,103 @@ strtod /* Can't trust HUGE_VAL */ #ifdef IEEE_Arith #ifdef Honor_FLT_ROUNDS - switch(bc.rounding) { + switch(Rounding) { case 0: /* toward 0 */ case 3: /* toward -infinity */ - word0(&rv) = Big0; - word1(&rv) = Big1; + word0(rv) = Big0; + word1(rv) = Big1; break; default: - word0(&rv) = Exp_mask; - word1(&rv) = 0; + word0(rv) = Exp_mask; + word1(rv) = 0; } #else /*Honor_FLT_ROUNDS*/ - word0(&rv) = Exp_mask; - word1(&rv) = 0; + word0(rv) = Exp_mask; + word1(rv) = 0; #endif /*Honor_FLT_ROUNDS*/ #ifdef SET_INEXACT /* set overflow bit */ - dval(&rv0) = 1e300; - dval(&rv0) *= dval(&rv0); + dval(rv0) = 1e300; + dval(rv0) *= dval(rv0); #endif #else /*IEEE_Arith*/ - word0(&rv) = Big0; - word1(&rv) = Big1; + word0(rv) = Big0; + word1(rv) = Big1; #endif /*IEEE_Arith*/ + if (bd0) + goto retfree; goto ret; } e1 >>= 4; for(j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) - dval(&rv) *= bigtens[j]; + dval(rv) *= bigtens[j]; /* The last multiplication could overflow. */ - word0(&rv) -= P*Exp_msk1; - dval(&rv) *= bigtens[j]; - if ((z = word0(&rv) & Exp_mask) + word0(rv) -= P*Exp_msk1; + dval(rv) *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-P)) goto ovfl; if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { /* set to largest number */ /* (Can't trust DBL_MAX) */ - word0(&rv) = Big0; - word1(&rv) = Big1; + word0(rv) = Big0; + word1(rv) = Big1; } else - word0(&rv) += P*Exp_msk1; + word0(rv) += P*Exp_msk1; } } else if (e1 < 0) { e1 = -e1; if ((i = e1 & 15)) - dval(&rv) /= tens[i]; + dval(rv) /= tens[i]; if (e1 >>= 4) { if (e1 >= 1 << n_bigtens) goto undfl; #ifdef Avoid_Underflow if (e1 & Scale_Bit) - bc.scale = 2*P; + scale = 2*P; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(&rv) *= tinytens[j]; - if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) + dval(rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) >> Exp_shift)) > 0) { /* scaled rv is denormal; clear j low bits */ if (j >= 32) { - word1(&rv) = 0; + word1(rv) = 0; if (j >= 53) - word0(&rv) = (P+2)*Exp_msk1; + word0(rv) = (P+2)*Exp_msk1; else - word0(&rv) &= 0xffffffff << (j-32); + word0(rv) &= 0xffffffff << j-32; } else - word1(&rv) &= 0xffffffff << j; + word1(rv) &= 0xffffffff << j; } #else for(j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) - dval(&rv) *= tinytens[j]; + dval(rv) *= tinytens[j]; /* The last multiplication could underflow. */ - dval(&rv0) = dval(&rv); - dval(&rv) *= tinytens[j]; - if (!dval(&rv)) { - dval(&rv) = 2.*dval(&rv0); - dval(&rv) *= tinytens[j]; + dval(rv0) = dval(rv); + dval(rv) *= tinytens[j]; + if (!dval(rv)) { + dval(rv) = 2.*dval(rv0); + dval(rv) *= tinytens[j]; #endif - if (!dval(&rv)) { + if (!dval(rv)) { undfl: - dval(&rv) = 0.; + dval(rv) = 0.; #ifndef NO_ERRNO errno = ERANGE; #endif + if (bd0) + goto retfree; goto ret; } #ifndef Avoid_Underflow - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; + word0(rv) = Tiny0; + word1(rv) = Tiny1; /* The refinement below will clean * this approximation up. */ @@ -2859,44 +1976,12 @@ strtod /* Put digits into bd: true value = bd * 10^e */ - bc.nd = nd; -#ifndef NO_STRTOD_BIGCOMP - bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ - /* to silence an erroneous warning about bc.nd0 */ - /* possibly not being initialized. */ - if (nd > strtod_diglim) { - /* ASSERT(strtod_diglim >= 18); 18 == one more than the */ - /* minimum number of decimal digits to distinguish double values */ - /* in IEEE arithmetic. */ - i = j = 18; - if (i > nd0) - j += bc.dplen; - for(;;) { - if (--j <= bc.dp1 && j >= bc.dp0) - j = bc.dp0 - 1; - if (s0[j] != '0') - break; - --i; - } - e += nd - i; - nd = i; - if (nd0 > nd) - nd0 = nd; - if (nd < 9) { /* must recompute y */ - y = 0; - for(i = 0; i < nd0; ++i) - y = 10*y + s0[i] - '0'; - for(j = bc.dp1; i < nd; ++i) - y = 10*y + s0[j++] - '0'; - } - } -#endif - bd0 = s2b(s0, nd0, nd, y, bc.dplen); + bd0 = s2b(s0, nd0, nd, y); for(;;) { bd = Balloc(bd0->k); Bcopy(bd, bd0); - bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ + bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ bs = i2b(1); if (e >= 0) { @@ -2913,11 +1998,11 @@ strtod bd2 -= bbe; bs2 = bb2; #ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) + if (Rounding != 1) bs2++; #endif #ifdef Avoid_Underflow - j = bbe - bc.scale; + j = bbe - scale; i = j + bbbits - 1; /* logb(rv) */ if (i < Emin) /* denormal */ j += P - Emin; @@ -2942,7 +2027,7 @@ strtod bb2 += j; bd2 += j; #ifdef Avoid_Underflow - bd2 += bc.scale; + bd2 += scale; #endif i = bb2 < bd2 ? bb2 : bd2; if (i > bs2) @@ -2967,116 +2052,99 @@ strtod if (bs2 > 0) bs = lshift(bs, bs2); delta = diff(bb, bd); - bc.dsign = delta->sign; + dsign = delta->sign; delta->sign = 0; i = cmp(delta, bs); -#ifndef NO_STRTOD_BIGCOMP - if (bc.nd > nd && i <= 0) { - if (bc.dsign) - break; /* Must use bigcomp(). */ #ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) { - if (i < 0) - break; - } - else -#endif - { - bc.nd = nd; - i = -1; /* Discarded digits make delta smaller. */ - } - } -#endif -#ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) { + if (Rounding != 1) { if (i < 0) { /* Error is less than an ulp */ if (!delta->x[0] && delta->wds <= 1) { /* exact */ #ifdef SET_INEXACT - bc.inexact = 0; + inexact = 0; #endif break; } - if (bc.rounding) { - if (bc.dsign) { - adj.d = 1.; + if (Rounding) { + if (dsign) { + adj = 1.; goto apply_adj; } } - else if (!bc.dsign) { - adj.d = -1.; - if (!word1(&rv) - && !(word0(&rv) & Frac_mask)) { - y = word0(&rv) & Exp_mask; + else if (!dsign) { + adj = -1.; + if (!word1(rv) + && !(word0(rv) & Frac_mask)) { + y = word0(rv) & Exp_mask; #ifdef Avoid_Underflow - if (!bc.scale || y > 2*P*Exp_msk1) + if (!scale || y > 2*P*Exp_msk1) #else if (y) #endif { delta = lshift(delta,Log2P); if (cmp(delta, bs) <= 0) - adj.d = -0.5; + adj = -0.5; } } apply_adj: #ifdef Avoid_Underflow - if (bc.scale && (y = word0(&rv) & Exp_mask) + if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(&adj) += (2*P+1)*Exp_msk1 - y; + word0(adj) += (2*P+1)*Exp_msk1 - y; #else #ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - word0(&rv) += P*Exp_msk1; - dval(&rv) += adj.d*ulp(dval(&rv)); - word0(&rv) -= P*Exp_msk1; + word0(rv) += P*Exp_msk1; + dval(rv) += adj*ulp(dval(rv)); + word0(rv) -= P*Exp_msk1; } else #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - dval(&rv) += adj.d*ulp(&rv); + dval(rv) += adj*ulp(dval(rv)); } break; } - adj.d = ratio(delta, bs); - if (adj.d < 1.) - adj.d = 1.; - if (adj.d <= 0x7ffffffe) { + adj = ratio(delta, bs); + if (adj < 1.) + adj = 1.; + if (adj <= 0x7ffffffe) { /* adj = rounding ? ceil(adj) : floor(adj); */ - y = adj.d; - if (y != adj.d) { - if (!((bc.rounding>>1) ^ bc.dsign)) + y = adj; + if (y != adj) { + if (!((Rounding>>1) ^ dsign)) y++; - adj.d = y; + adj = y; } } #ifdef Avoid_Underflow - if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(&adj) += (2*P+1)*Exp_msk1 - y; + if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; #else #ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - word0(&rv) += P*Exp_msk1; - adj.d *= ulp(dval(&rv)); - if (bc.dsign) - dval(&rv) += adj.d; + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; else - dval(&rv) -= adj.d; - word0(&rv) -= P*Exp_msk1; + dval(rv) -= adj; + word0(rv) -= P*Exp_msk1; goto cont; } #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - adj.d *= ulp(&rv); - if (bc.dsign) { - if (word0(&rv) == Big0 && word1(&rv) == Big1) + adj *= ulp(dval(rv)); + if (dsign) { + if (word0(rv) == Big0 && word1(rv) == Big1) goto ovfl; - dval(&rv) += adj.d; + dval(rv) += adj; } else - dval(&rv) -= adj.d; + dval(rv) -= adj; goto cont; } #endif /*Honor_FLT_ROUNDS*/ @@ -3085,25 +2153,25 @@ strtod /* Error is less than half an ulp -- check for * special case of mantissa a power of two. */ - if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask + if (dsign || word1(rv) || word0(rv) & Bndry_mask #ifdef IEEE_Arith #ifdef Avoid_Underflow - || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 + || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 #else - || (word0(&rv) & Exp_mask) <= Exp_msk1 + || (word0(rv) & Exp_mask) <= Exp_msk1 #endif #endif ) { #ifdef SET_INEXACT if (!delta->x[0] && delta->wds <= 1) - bc.inexact = 0; + inexact = 0; #endif break; } if (!delta->x[0] && delta->wds <= 1) { /* exact result */ #ifdef SET_INEXACT - bc.inexact = 0; + inexact = 0; #endif break; } @@ -3114,72 +2182,62 @@ strtod } if (i == 0) { /* exactly half-way between */ - if (bc.dsign) { - if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 - && word1(&rv) == ( + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == ( #ifdef Avoid_Underflow - (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) + (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : #endif 0xffffffff)) { /*boundary case -- increment exponent*/ - word0(&rv) = (word0(&rv) & Exp_mask) + word0(rv) = (word0(rv) & Exp_mask) + Exp_msk1 #ifdef IBM | Exp_msk1 >> 4 #endif ; - word1(&rv) = 0; + word1(rv) = 0; #ifdef Avoid_Underflow - bc.dsign = 0; + dsign = 0; #endif break; } } - else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { drop_down: /* boundary case -- decrement exponent */ #ifdef Sudden_Underflow /*{{*/ - L = word0(&rv) & Exp_mask; + L = word0(rv) & Exp_mask; #ifdef IBM if (L < Exp_msk1) #else #ifdef Avoid_Underflow - if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) + if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) #else if (L <= Exp_msk1) #endif /*Avoid_Underflow*/ #endif /*IBM*/ - { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } goto undfl; - } L -= Exp_msk1; #else /*Sudden_Underflow}{*/ #ifdef Avoid_Underflow - if (bc.scale) { - L = word0(&rv) & Exp_mask; + if (scale) { + L = word0(rv) & Exp_mask; if (L <= (2*P+1)*Exp_msk1) { if (L > (P+2)*Exp_msk1) /* round even ==> */ /* accept rv */ break; /* rv = smallest denormal */ - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } goto undfl; } } #endif /*Avoid_Underflow*/ - L = (word0(&rv) & Exp_mask) - Exp_msk1; + L = (word0(rv) & Exp_mask) - Exp_msk1; #endif /*Sudden_Underflow}}*/ - word0(&rv) = L | Bndry_mask1; - word1(&rv) = 0xffffffff; + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; #ifdef IBM goto cont; #else @@ -3187,42 +2245,32 @@ strtod #endif } #ifndef ROUND_BIASED - if (!(word1(&rv) & LSB)) + if (!(word1(rv) & LSB)) break; #endif - if (bc.dsign) - dval(&rv) += ulp(&rv); + if (dsign) + dval(rv) += ulp(dval(rv)); #ifndef ROUND_BIASED else { - dval(&rv) -= ulp(&rv); + dval(rv) -= ulp(dval(rv)); #ifndef Sudden_Underflow - if (!dval(&rv)) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } + if (!dval(rv)) goto undfl; - } #endif } #ifdef Avoid_Underflow - bc.dsign = 1 - bc.dsign; + dsign = 1 - dsign; #endif #endif break; } if ((aadj = ratio(delta, bs)) <= 2.) { - if (bc.dsign) + if (dsign) aadj = aadj1 = 1.; - else if (word1(&rv) || word0(&rv) & Bndry_mask) { + else if (word1(rv) || word0(rv) & Bndry_mask) { #ifndef Sudden_Underflow - if (word1(&rv) == Tiny1 && !word0(&rv)) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } + if (word1(rv) == Tiny1 && !word0(rv)) goto undfl; - } #endif aadj = 1.; aadj1 = -1.; @@ -3240,9 +2288,9 @@ strtod } else { aadj *= 0.5; - aadj1 = bc.dsign ? aadj : -aadj; + aadj1 = dsign ? aadj : -aadj; #ifdef Check_FLT_ROUNDS - switch(bc.rounding) { + switch(Rounding) { case 2: /* towards +infinity */ aadj1 -= 0.5; break; @@ -3255,72 +2303,65 @@ strtod aadj1 += 0.5; #endif /*Check_FLT_ROUNDS*/ } - y = word0(&rv) & Exp_mask; + y = word0(rv) & Exp_mask; /* Check for overflow */ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(&rv0) = dval(&rv); - word0(&rv) -= P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if ((word0(&rv) & Exp_mask) >= + dval(rv0) = dval(rv); + word0(rv) -= P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + if ((word0(rv) & Exp_mask) >= Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(&rv0) == Big0 && word1(&rv0) == Big1) + if (word0(rv0) == Big0 && word1(rv0) == Big1) goto ovfl; - word0(&rv) = Big0; - word1(&rv) = Big1; + word0(rv) = Big0; + word1(rv) = Big1; goto cont; } else - word0(&rv) += P*Exp_msk1; + word0(rv) += P*Exp_msk1; } else { #ifdef Avoid_Underflow - if (bc.scale && y <= 2*P*Exp_msk1) { + if (scale && y <= 2*P*Exp_msk1) { if (aadj <= 0x7fffffff) { if ((z = aadj) <= 0) z = 1; aadj = z; - aadj1 = bc.dsign ? aadj : -aadj; + aadj1 = dsign ? aadj : -aadj; } - dval(&aadj2) = aadj1; - word0(&aadj2) += (2*P+1)*Exp_msk1 - y; - aadj1 = dval(&aadj2); + word0(aadj1) += (2*P+1)*Exp_msk1 - y; } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; #else #ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - dval(&rv0) = dval(&rv); - word0(&rv) += P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + dval(rv0) = dval(rv); + word0(rv) += P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; #ifdef IBM - if ((word0(&rv) & Exp_mask) < P*Exp_msk1) + if ((word0(rv) & Exp_mask) < P*Exp_msk1) #else - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) #endif { - if (word0(&rv0) == Tiny0 - && word1(&rv0) == Tiny1) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } + if (word0(rv0) == Tiny0 + && word1(rv0) == Tiny1) goto undfl; - } - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; + word0(rv) = Tiny0; + word1(rv) = Tiny1; goto cont; } else - word0(&rv) -= P*Exp_msk1; + word0(rv) -= P*Exp_msk1; } else { - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; } #else /*Sudden_Underflow*/ /* Compute adj so that the IEEE rounding rules will @@ -3332,33 +2373,31 @@ strtod */ if (y <= (P-1)*Exp_msk1 && aadj > 1.) { aadj1 = (double)(int)(aadj + 0.5); - if (!bc.dsign) + if (!dsign) aadj1 = -aadj1; } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ } - z = word0(&rv) & Exp_mask; + z = word0(rv) & Exp_mask; #ifndef SET_INEXACT - if (bc.nd == nd) { #ifdef Avoid_Underflow - if (!bc.scale) + if (!scale) #endif if (y == z) { /* Can we stop now? */ L = (Long)aadj; aadj -= L; /* The tolerances below are conservative. */ - if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { if (aadj < .4999999 || aadj > .5000001) break; } else if (aadj < .4999999/FLT_RADIX) break; } - } #endif cont: Bfree(bb); @@ -3366,53 +2405,168 @@ strtod Bfree(bs); Bfree(delta); } - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); -#ifndef NO_STRTOD_BIGCOMP - if (bc.nd > nd) - bigcomp(&rv, s0, &bc); -#endif #ifdef SET_INEXACT - if (bc.inexact) { + if (inexact) { if (!oldinexact) { - word0(&rv0) = Exp_1 + (70 << Exp_shift); - word1(&rv0) = 0; - dval(&rv0) += 1.; + word0(rv0) = Exp_1 + (70 << Exp_shift); + word1(rv0) = 0; + dval(rv0) += 1.; } } else if (!oldinexact) clear_inexact(); #endif #ifdef Avoid_Underflow - if (bc.scale) { - word0(&rv0) = Exp_1 - 2*P*Exp_msk1; - word1(&rv0) = 0; - dval(&rv) *= dval(&rv0); + if (scale) { + word0(rv0) = Exp_1 - 2*P*Exp_msk1; + word1(rv0) = 0; + dval(rv) *= dval(rv0); #ifndef NO_ERRNO /* try to avoid the bug of testing an 8087 register value */ #ifdef IEEE_Arith - if (!(word0(&rv) & Exp_mask)) + if (!(word0(rv) & Exp_mask)) #else - if (word0(&rv) == 0 && word1(&rv) == 0) + if (word0(rv) == 0 && word1(rv) == 0) #endif errno = ERANGE; #endif } #endif /* Avoid_Underflow */ #ifdef SET_INEXACT - if (bc.inexact && !(word0(&rv) & Exp_mask)) { + if (inexact && !(word0(rv) & Exp_mask)) { /* set underflow bit */ - dval(&rv0) = 1e-300; - dval(&rv0) *= dval(&rv0); + dval(rv0) = 1e-300; + dval(rv0) *= dval(rv0); } #endif + retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); ret: if (se) *se = (char *)s; - return sign ? -dval(&rv) : dval(&rv); + return sign ? -dval(rv) : dval(rv); + } + + static int +quorem +#ifdef KR_headers + (b, S) Bigint *b, *S; +#else + (Bigint *b, Bigint *S) +#endif +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; } #ifndef MULTIPLE_THREADS @@ -3517,10 +2671,10 @@ freedtoa(char *s) char * dtoa #ifdef KR_headers - (dd, mode, ndigits, decpt, sign, rve) - double dd; int mode, ndigits, *decpt, *sign; char **rve; + (d, mode, ndigits, decpt, sign, rve) + double d; int mode, ndigits, *decpt, *sign; char **rve; #else - (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) + (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) #endif { /* Arguments ndigits, decpt, sign are similar to those @@ -3557,7 +2711,7 @@ dtoa to hold the suppressed trailing zeros. */ - int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, spec_case, try_quick; Long L; @@ -3566,8 +2720,7 @@ dtoa ULong x; #endif Bigint *b, *b1, *delta, *mlo, *mhi, *S; - U d2, eps, u; - double ds; + double d2, ds, eps; char *s, *s0; #ifdef SET_INEXACT int inexact, oldinexact; @@ -3593,35 +2746,34 @@ dtoa } #endif - u.d = dd; - if (word0(&u) & Sign_bit) { + if (word0(d) & Sign_bit) { /* set sign for everything, including 0's and NaNs */ *sign = 1; - word0(&u) &= ~Sign_bit; /* clear sign bit */ + word0(d) &= ~Sign_bit; /* clear sign bit */ } else *sign = 0; #if defined(IEEE_Arith) + defined(VAX) #ifdef IEEE_Arith - if ((word0(&u) & Exp_mask) == Exp_mask) + if ((word0(d) & Exp_mask) == Exp_mask) #else - if (word0(&u) == 0x8000) + if (word0(d) == 0x8000) #endif { /* Infinity or NaN */ *decpt = 9999; #ifdef IEEE_Arith - if (!word1(&u) && !(word0(&u) & 0xfffff)) + if (!word1(d) && !(word0(d) & 0xfffff)) return nrv_alloc("Infinity", rve, 8); #endif return nrv_alloc("NaN", rve, 3); } #endif #ifdef IBM - dval(&u) += 0; /* normalize */ + dval(d) += 0; /* normalize */ #endif - if (!dval(&u)) { + if (!dval(d)) { *decpt = 1; return nrv_alloc("0", rve, 1); } @@ -3640,18 +2792,18 @@ dtoa } #endif - b = d2b(&u, &be, &bbits); + b = d2b(dval(d), &be, &bbits); #ifdef Sudden_Underflow - i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); #else - if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { + if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { #endif - dval(&d2) = dval(&u); - word0(&d2) &= Frac_mask1; - word0(&d2) |= Exp_11; + dval(d2) = dval(d); + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; #ifdef IBM - if (j = 11 - hi0bits(word0(&d2) & Frac_mask)) - dval(&d2) /= 1 << j; + if (j = 11 - hi0bits(word0(d2) & Frac_mask)) + dval(d2) /= 1 << j; #endif /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 @@ -3688,21 +2840,21 @@ dtoa /* d is denormalized */ i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) - : word1(&u) << (32 - i); - dval(&d2) = x; - word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ + x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 + : word1(d) << 32 - i; + dval(d2) = x; + word0(d2) -= 31*Exp_msk1; /* adjust exponent */ i -= (Bias + (P-1) - 1) + 1; denorm = 1; } #endif - ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; k = (int)ds; if (ds < 0. && ds != k) k--; /* want k = floor(ds) */ k_check = 1; if (k >= 0 && k <= Ten_pmax) { - if (dval(&u) < tens[k]) + if (dval(d) < tens[k]) k--; k_check = 0; } @@ -3741,11 +2893,10 @@ dtoa try_quick = 0; } leftright = 1; - ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ - /* silence erroneous "gcc -Wall" warning. */ switch(mode) { case 0: case 1: + ilim = ilim1 = -1; i = 18; ndigits = 0; break; @@ -3779,7 +2930,7 @@ dtoa /* Try to get by with floating-point arithmetic. */ i = 0; - dval(&d2) = dval(&u); + dval(d2) = dval(d); k0 = k; ilim0 = ilim; ieps = 2; /* conservative */ @@ -3789,7 +2940,7 @@ dtoa if (j & Bletch) { /* prevent overflows */ j &= Bletch - 1; - dval(&u) /= bigtens[n_bigtens-1]; + dval(d) /= bigtens[n_bigtens-1]; ieps++; } for(; j; j >>= 1, i++) @@ -3797,32 +2948,32 @@ dtoa ieps++; ds *= bigtens[i]; } - dval(&u) /= ds; + dval(d) /= ds; } else if ((j1 = -k)) { - dval(&u) *= tens[j1 & 0xf]; + dval(d) *= tens[j1 & 0xf]; for(j = j1 >> 4; j; j >>= 1, i++) if (j & 1) { ieps++; - dval(&u) *= bigtens[i]; + dval(d) *= bigtens[i]; } } - if (k_check && dval(&u) < 1. && ilim > 0) { + if (k_check && dval(d) < 1. && ilim > 0) { if (ilim1 <= 0) goto fast_failed; ilim = ilim1; k--; - dval(&u) *= 10.; + dval(d) *= 10.; ieps++; } - dval(&eps) = ieps*dval(&u) + 7.; - word0(&eps) -= (P-1)*Exp_msk1; + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; if (ilim == 0) { S = mhi = 0; - dval(&u) -= 5.; - if (dval(&u) > dval(&eps)) + dval(d) -= 5.; + if (dval(d) > dval(eps)) goto one_digit; - if (dval(&u) < -dval(&eps)) + if (dval(d) < -dval(eps)) goto no_digits; goto fast_failed; } @@ -3831,34 +2982,34 @@ dtoa /* Use Steele & White method of only * generating digits needed. */ - dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); + dval(eps) = 0.5/tens[ilim-1] - dval(eps); for(i = 0;;) { - L = dval(&u); - dval(&u) -= L; + L = dval(d); + dval(d) -= L; *s++ = '0' + (int)L; - if (dval(&u) < dval(&eps)) + if (dval(d) < dval(eps)) goto ret1; - if (1. - dval(&u) < dval(&eps)) + if (1. - dval(d) < dval(eps)) goto bump_up; if (++i >= ilim) break; - dval(&eps) *= 10.; - dval(&u) *= 10.; + dval(eps) *= 10.; + dval(d) *= 10.; } } else { #endif /* Generate ilim digits, then fix them up. */ - dval(&eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u)); - if (!(dval(&u) -= L)) + dval(eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d)); + if (!(dval(d) -= L)) ilim = i; *s++ = '0' + (int)L; if (i == ilim) { - if (dval(&u) > 0.5 + dval(&eps)) + if (dval(d) > 0.5 + dval(eps)) goto bump_up; - else if (dval(&u) < 0.5 - dval(&eps)) { + else if (dval(d) < 0.5 - dval(eps)) { while(*--s == '0'); s++; goto ret1; @@ -3871,7 +3022,7 @@ dtoa #endif fast_failed: s = s0; - dval(&u) = dval(&d2); + dval(d) = dval(d2); k = k0; ilim = ilim0; } @@ -3883,22 +3034,22 @@ dtoa ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = 0; - if (ilim < 0 || dval(&u) <= 5*ds) + if (ilim < 0 || dval(d) <= 5*ds) goto no_digits; goto one_digit; } - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u) / ds); - dval(&u) -= L*ds; + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d) / ds); + dval(d) -= L*ds; #ifdef Check_FLT_ROUNDS /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(&u) < 0) { + if (dval(d) < 0) { L--; - dval(&u) += ds; + dval(d) += ds; } #endif *s++ = '0' + (int)L; - if (!dval(&u)) { + if (!dval(d)) { #ifdef SET_INEXACT inexact = 0; #endif @@ -3912,8 +3063,8 @@ dtoa case 2: goto bump_up; } #endif - dval(&u) += dval(&u); - if (dval(&u) > ds || (dval(&u) == ds && L & 1)) { + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { bump_up: while(*--s == '9') if (s == s0) { @@ -3978,9 +3129,9 @@ dtoa && Rounding == 1 #endif ) { - if (!word1(&u) && !(word0(&u) & Bndry_mask) + if (!word1(d) && !(word0(d) & Bndry_mask) #ifndef Sudden_Underflow - && word0(&u) & (Exp_mask & ~Exp_msk1) + && word0(d) & (Exp_mask & ~Exp_msk1) #endif ) { /* The special case */ @@ -4000,16 +3151,22 @@ dtoa #ifdef Pack_32 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)) i = 32 - i; -#define iInc 28 #else if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) i = 16 - i; -#define iInc 12 #endif - i = dshift(S, s2); - b2 += i; - m2 += i; - s2 += i; + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } if (b2 > 0) b = lshift(b, b2); if (s2 > 0) @@ -4060,7 +3217,7 @@ dtoa j1 = delta->sign ? 1 : cmp(b, delta); Bfree(delta); #ifndef ROUND_BIASED - if (j1 == 0 && mode != 1 && !(word1(&u) & 1) + if (j1 == 0 && mode != 1 && !(word1(d) & 1) #ifdef Honor_FLT_ROUNDS && Rounding >= 1 #endif @@ -4077,11 +3234,11 @@ dtoa goto ret; } #endif - if (j < 0 || (j == 0 && mode != 1 + if (j < 0 || j == 0 && mode != 1 #ifndef ROUND_BIASED - && !(word1(&u) & 1) + && !(word1(d) & 1) #endif - )) { + ) { if (!b->x[0] && b->wds <= 1) { #ifdef SET_INEXACT inexact = 0; @@ -4098,7 +3255,7 @@ dtoa if (j1 > 0) { b = lshift(b, 1); j1 = cmp(b, S); - if ((j1 > 0 || (j1 == 0 && dig & 1)) + if ((j1 > 0 || j1 == 0 && dig & 1) && dig++ == '9') goto round_9_up; } @@ -4158,7 +3315,7 @@ dtoa #endif b = lshift(b, 1); j = cmp(b, S); - if (j > 0 || (j == 0 && dig & 1)) { + if (j > 0 || j == 0 && dig & 1) { roundoff: while(*--s == '9') if (s == s0) { @@ -4186,9 +3343,9 @@ dtoa #ifdef SET_INEXACT if (inexact) { if (!oldinexact) { - word0(&u) = Exp_1 + (70 << Exp_shift); - word1(&u) = 0; - dval(&u) += 1.; + word0(d) = Exp_1 + (70 << Exp_shift); + word1(d) = 0; + dval(d) += 1.; } } else if (!oldinexact) diff --git a/base/third_party/dmg_fp/gcc_warnings.patch b/base/third_party/dmg_fp/gcc_warnings.patch index 2db3e32..1aa6a25 100644 --- a/base/third_party/dmg_fp/gcc_warnings.patch +++ b/base/third_party/dmg_fp/gcc_warnings.patch @@ -1,42 +1,70 @@ Index: dtoa.cc --- dtoa.cc (old copy) +++ dtoa.cc (working copy) -@@ -179,6 +179,9 @@ - * used for input more than STRTOD_DIGLIM digits long (default 40). +@@ -172,6 +172,10 @@ */ -+#define IEEE_8087 -+#define NO_HEX_FP -+ + #define IEEE_8087 ++#if defined(__GNUC__) ++// Make gcc 4.3+ warnings about parentheses non-fatal warnings. ++#pragma GCC diagnostic warning "-Wparentheses" ++#endif + #ifndef Long #define Long long +@@ -515,7 +519,7 @@ Balloc #endif -@@ -280,9 +283,7 @@ - #include "math.h" - #endif - --#ifdef __cplusplus --extern "C" { --#endif -+namespace dmg_fp { - #ifndef CONST - #ifdef KR_headers -@@ -511,11 +512,9 @@ - - #define Kmax 7 + ACQUIRE_DTOA_LOCK(0); +- if (rv = freelist[k]) { ++ if ((rv = freelist[k])) { + freelist[k] = rv->next; + } + else { +@@ -794,7 +798,7 @@ mult + xc0 = c->x; + #ifdef ULLong + for(; xb < xbe; xc0++) { +- if (y = *xb++) { ++ if ((y = *xb++)) { + x = xa; + xc = xc0; + carry = 0; +@@ -876,7 +880,7 @@ pow5mult + int i; + static int p05[3] = { 5, 25, 125 }; --#ifdef __cplusplus --extern "C" double strtod(const char *s00, char **se); --extern "C" char *dtoa(double d, int mode, int ndigits, -+double strtod(const char *s00, char **se); -+char *dtoa(double d, int mode, int ndigits, - int *decpt, int *sign, char **rve); --#endif +- if (i = k & 3) ++ if ((i = k & 3)) + b = multadd(b, p05[i-1], 0); - struct - Bigint { -@@ -1527,7 +1526,7 @@ + if (!(k >>= 2)) +@@ -957,7 +961,7 @@ lshift + z = *x++ >> k1; + } + while(x < xe); +- if (*x1 = z) ++ if ((*x1 = z)) + ++n1; + } + #else +@@ -1259,12 +1263,12 @@ d2b + z |= Exp_msk11; + #endif + #else +- if (de = (int)(d0 >> Exp_shift)) ++ if ((de = (int)(d0 >> Exp_shift))) + z |= Exp_msk1; + #endif + #ifdef Pack_32 +- if (y = d1) { +- if (k = lo0bits(&y)) { ++ if ((y = d1)) { ++ if ((k = lo0bits(&y))) { + x[0] = y | z << 32 - k; + z >>= k; + } +@@ -1452,13 +1456,13 @@ match #ifdef KR_headers (sp, t) char **sp, *t; #else @@ -45,7 +73,50 @@ Index: dtoa.cc #endif { int c, d; -@@ -3431,7 +3430,7 @@ + CONST char *s = *sp; + +- while(d = *t++) { ++ while((d = *t++)) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) +@@ -1490,7 +1494,7 @@ hexnan + ++s; + if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')) + s += 2; +- while(c = *(CONST unsigned char*)++s) { ++ while((c = *(CONST unsigned char*)++s)) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'a' && c <= 'f') +@@ -1518,7 +1522,7 @@ hexnan + *sp = s + 1; + break; + } +- } while(c = *++s); ++ } while((c = *++s)); + break; + } + #endif +@@ -1852,7 +1856,7 @@ strtod + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { +- if (i = e1 & 15) ++ if ((i = e1 & 15)) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { +@@ -1912,7 +1916,7 @@ strtod + } + else if (e1 < 0) { + e1 = -e1; +- if (i = e1 & 15) ++ if ((i = e1 & 15)) + dval(rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) +@@ -2580,7 +2584,7 @@ rv_alloc(int i) j = sizeof(ULong); for(k = 0; @@ -54,7 +125,7 @@ Index: dtoa.cc j <<= 1) k++; r = (int*)Balloc(k); -@@ -3447,7 +3446,7 @@ +@@ -2596,13 +2600,13 @@ rv_alloc(int i) #ifdef KR_headers nrv_alloc(s, rve, n) char *s, **rve; int n; #else @@ -63,15 +134,68 @@ Index: dtoa.cc #endif { char *rv, *t; -@@ -4202,6 +4201,5 @@ - *rve = s; - return s0; - } --#ifdef __cplusplus --} --#endif -+ -+} // namespace dmg_fp + + t = rv = rv_alloc(n); +- while(*t = *s++) t++; ++ while((*t = *s++)) t++; + if (rve) + *rve = t; + return rv; +@@ -2707,7 +2711,7 @@ dtoa + to hold the suppressed trailing zeros. + */ + +- int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, ++ int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; +@@ -2792,7 +2796,7 @@ dtoa + #ifdef Sudden_Underflow + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); + #else +- if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { ++ if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { + #endif + dval(d2) = dval(d); + word0(d2) &= Frac_mask1; +@@ -2946,7 +2950,7 @@ dtoa + } + dval(d) /= ds; + } +- else if (j1 = -k) { ++ else if ((j1 = -k)) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { +@@ -3107,7 +3111,7 @@ dtoa + Bfree(b); + b = b1; + } +- if (j = b5 - m5) ++ if ((j = b5 - m5)) + b = pow5mult(b, j); + } + else +@@ -3145,7 +3149,7 @@ dtoa + * can do shifts and ors to compute the numerator for q. + */ + #ifdef Pack_32 +- if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) ++ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)) + i = 32 - i; + #else + if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) +@@ -3322,7 +3326,9 @@ dtoa + ++*s++; + } + else { ++#ifdef Honor_FLT_ROUNDS + trimzeros: ++#endif + while(*--s == '0'); + s++; + } Index: g_fmt.cc --- g_fmt.cc (old copy) +++ g_fmt.cc (new copy) |