Index: base/third_party/dmg_fp/dtoa.cc |
diff --git a/base/third_party/dmg_fp/dtoa.cc b/base/third_party/dmg_fp/dtoa.cc |
index ba49857514bdec0d20afe22fb41c9ba3585db374..6ab2aefb0bc86e9009d637483f31973ea62ee00b 100644 |
--- a/base/third_party/dmg_fp/dtoa.cc |
+++ b/base/third_party/dmg_fp/dtoa.cc |
@@ -103,7 +103,12 @@ |
* #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. |
+ * 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.) |
* #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, |
@@ -147,11 +152,6 @@ |
* 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,13 +169,18 @@ |
* 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 |
-#if defined(__GNUC__) |
-// Make gcc 4.3+ warnings about parentheses non-fatal warnings. |
-#pragma GCC diagnostic warning "-Wparentheses" |
-#endif |
+#define NO_HEX_FP |
#ifndef Long |
#define Long long |
@@ -196,6 +201,12 @@ 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(); |
@@ -230,6 +241,7 @@ static double private_mem[PRIVATE_mem], *pmem_next = private_mem; |
#endif |
#else |
#undef INFNAN_CHECK |
+#define NO_STRTOD_BIGCOMP |
#endif |
#include "errno.h" |
@@ -287,24 +299,23 @@ 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) ((ULong *)&x)[1] |
-#define word1(x) ((ULong *)&x)[0] |
+#define word0(x) (x)->L[1] |
+#define word1(x) (x)->L[0] |
#else |
-#define word0(x) ((ULong *)&x)[0] |
-#define word1(x) ((ULong *)&x)[1] |
+#define word0(x) (x)->L[0] |
+#define word1(x) (x)->L[1] |
#endif |
-#else |
-#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] |
+#define dval(x) (x)->d |
+ |
+#ifndef STRTOD_DIGLIM |
+#define STRTOD_DIGLIM 40 |
#endif |
-#define dval(x) ((U*)&x)->d |
+ |
+#ifdef DIGLIM_DEBUG |
+extern int strtod_diglim; |
+#else |
+#define strtod_diglim STRTOD_DIGLIM |
#endif |
/* The following definition of Storeinc is appropriate for MIPS processors. |
@@ -332,7 +343,9 @@ typedef union { double d; ULong L[2]; } U; |
#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 |
@@ -387,7 +400,10 @@ typedef union { double d; ULong L[2]; } U; |
#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 */ |
@@ -413,7 +429,10 @@ typedef union { double d; ULong L[2]; } U; |
#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 |
@@ -457,6 +476,10 @@ 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 |
@@ -487,7 +510,7 @@ extern double rnd_prod(double, double), rnd_quot(double, double); |
#define FREE_DTOA_LOCK(n) /*nothing*/ |
#endif |
-#define Kmax 15 |
+#define Kmax 7 |
double strtod(const char *s00, char **se); |
char *dtoa(double d, int mode, int ndigits, |
@@ -519,9 +542,10 @@ Balloc |
#endif |
ACQUIRE_DTOA_LOCK(0); |
- if ((rv = freelist[k])) { |
+ /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ |
+ /* but this case seems very unlikely. */ |
+ if (k <= Kmax && (rv = freelist[k])) |
freelist[k] = rv->next; |
- } |
else { |
x = 1 << k; |
#ifdef Omit_Private_Memory |
@@ -529,7 +553,7 @@ Balloc |
#else |
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) |
/sizeof(double); |
- if (pmem_next - private_mem + len <= PRIVATE_mem) { |
+ if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { |
rv = (Bigint*)pmem_next; |
pmem_next += len; |
} |
@@ -553,10 +577,18 @@ Bfree |
#endif |
{ |
if (v) { |
- ACQUIRE_DTOA_LOCK(0); |
- v->next = freelist[v->k]; |
- freelist[v->k] = v; |
- FREE_DTOA_LOCK(0); |
+ 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); |
+ } |
} |
} |
@@ -623,9 +655,9 @@ multadd |
static Bigint * |
s2b |
#ifdef KR_headers |
- (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; |
+ (s, nd0, nd, y9, dplen) CONST char *s; int nd0, nd, dplen; ULong y9; |
#else |
- (CONST char *s, int nd0, int nd, ULong y9) |
+ (CONST char *s, int nd0, int nd, ULong y9, int dplen) |
#endif |
{ |
Bigint *b; |
@@ -649,10 +681,10 @@ s2b |
s += 9; |
do b = multadd(b, 10, *s++ - '0'); |
while(++i < nd0); |
- s++; |
+ s += dplen; |
} |
else |
- s += 10; |
+ s += dplen + 9; |
for(; i < nd; i++) |
b = multadd(b, 10, *s++ - '0'); |
return b; |
@@ -661,12 +693,12 @@ s2b |
static int |
hi0bits |
#ifdef KR_headers |
- (x) register ULong x; |
+ (x) ULong x; |
#else |
- (register ULong x) |
+ (ULong x) |
#endif |
{ |
- register int k = 0; |
+ int k = 0; |
if (!(x & 0xffff0000)) { |
k = 16; |
@@ -700,8 +732,8 @@ lo0bits |
(ULong *y) |
#endif |
{ |
- register int k; |
- register ULong x = *y; |
+ int k; |
+ ULong x = *y; |
if (x & 7) { |
if (x & 1) |
@@ -1116,13 +1148,13 @@ diff |
static double |
ulp |
#ifdef KR_headers |
- (x) double x; |
+ (x) U *x; |
#else |
- (double x) |
+ (U *x) |
#endif |
{ |
- register Long L; |
- double a; |
+ Long L; |
+ U u; |
L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; |
#ifndef Avoid_Underflow |
@@ -1133,26 +1165,26 @@ ulp |
#ifdef IBM |
L |= Exp_msk1 >> 4; |
#endif |
- word0(a) = L; |
- word1(a) = 0; |
+ word0(&u) = L; |
+ word1(&u) = 0; |
#ifndef Avoid_Underflow |
#ifndef Sudden_Underflow |
} |
else { |
L = -L >> Exp_shift; |
if (L < Exp_shift) { |
- word0(a) = 0x80000 >> L; |
- word1(a) = 0; |
+ word0(&u) = 0x80000 >> L; |
+ word1(&u) = 0; |
} |
else { |
- word0(a) = 0; |
+ word0(&u) = 0; |
L -= Exp_shift; |
- word1(a) = L >= 31 ? 1 : 1 << 31 - L; |
+ word1(&u) = L >= 31 ? 1 : 1 << 31 - L; |
} |
} |
#endif |
#endif |
- return dval(a); |
+ return dval(&u); |
} |
static double |
@@ -1165,12 +1197,12 @@ b2d |
{ |
ULong *xa, *xa0, w, y, z; |
int k; |
- double d; |
+ U 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; |
@@ -1183,16 +1215,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; |
@@ -1216,21 +1248,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) double d; int *e, *bits; |
+ (d, e, bits) U *d; int *e, *bits; |
#else |
- (double d, int *e, int *bits) |
+ (U *d, int *e, int *bits) |
#endif |
{ |
Bigint *b; |
@@ -1269,7 +1301,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 |
@@ -1280,10 +1312,6 @@ 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 |
@@ -1371,11 +1399,11 @@ ratio |
(Bigint *a, Bigint *b) |
#endif |
{ |
- double da, db; |
+ U 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 |
@@ -1383,25 +1411,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 |
@@ -1441,6 +1469,48 @@ 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 |
@@ -1476,15 +1546,17 @@ match |
static void |
hexnan |
#ifdef KR_headers |
- (rvp, sp) double *rvp; CONST char **sp; |
+ (rvp, sp) U *rvp; CONST char **sp; |
#else |
- (double *rvp, CONST char **sp) |
+ (U *rvp, CONST char **sp) |
#endif |
{ |
ULong c, x[2]; |
CONST char *s; |
- int havedig, udx0, xshift; |
+ int c1, havedig, udx0, xshift; |
+ if (!hexdig['0']) |
+ hexdig_init(); |
x[0] = x[1] = 0; |
havedig = xshift = 0; |
udx0 = 1; |
@@ -1495,12 +1567,8 @@ hexnan |
if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')) |
s += 2; |
while((c = *(CONST unsigned char*)++s)) { |
- 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'; |
+ if ((c1 = hexdig[c])) |
+ c = c1 & 0xf; |
else if (c <= ' ') { |
if (udx0 && havedig) { |
udx0 = 0; |
@@ -1537,13 +1605,818 @@ 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 |
@@ -1552,29 +2425,27 @@ strtod |
(CONST char *s00, char **se) |
#endif |
{ |
-#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; |
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; |
+ int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; |
CONST char *s, *s0, *s1; |
- double aadj, aadj1, adj, rv, rv0; |
+ double aadj, aadj1; |
Long L; |
+ U aadj2, adj, rv, rv0; |
ULong y, z; |
+ BCinfo bc; |
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; |
#ifdef SET_INEXACT |
- int inexact, oldinexact; |
+ int oldinexact; |
#endif |
#ifdef Honor_FLT_ROUNDS /*{*/ |
- int Rounding; |
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ |
- Rounding = Flt_Rounds; |
+ bc.rounding = Flt_Rounds; |
#else /*}{*/ |
- Rounding = 1; |
+ bc.rounding = 1; |
switch(fegetround()) { |
- case FE_TOWARDZERO: Rounding = 0; break; |
- case FE_UPWARD: Rounding = 2; break; |
- case FE_DOWNWARD: Rounding = 3; |
+ case FE_TOWARDZERO: bc.rounding = 0; break; |
+ case FE_UPWARD: bc.rounding = 2; break; |
+ case FE_DOWNWARD: bc.rounding = 3; |
} |
#endif /*}}*/ |
#endif /*}*/ |
@@ -1582,8 +2453,8 @@ strtod |
CONST char *s2; |
#endif |
- sign = nz0 = nz = 0; |
- dval(rv) = 0.; |
+ sign = nz0 = nz = bc.dplen = bc.uflchk = 0; |
+ dval(&rv) = 0.; |
for(s = s00;;s++) switch(*s) { |
case '-': |
sign = 1; |
@@ -1606,6 +2477,18 @@ 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) |
@@ -1619,6 +2502,7 @@ 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) { |
@@ -1640,6 +2524,8 @@ strtod |
#endif |
if (c == '.') { |
c = *++s; |
+ bc.dp1 = s - s0; |
+ bc.dplen = bc.dp1 - bc.dp0; |
if (!nd) { |
for(; c == '0'; c = *++s) |
nz++; |
@@ -1711,23 +2597,24 @@ strtod |
if (!nz && !nz0) { |
#ifdef INFNAN_CHECK |
/* Check for Nan and Infinity */ |
- switch(c) { |
+ if (!bc.dplen) |
+ 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); |
@@ -1742,7 +2629,7 @@ strtod |
} |
goto ret; |
} |
- e1 = e -= nf; |
+ bc.e0 = 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 |
@@ -1752,13 +2639,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 |
@@ -1778,11 +2665,11 @@ strtod |
#ifdef Honor_FLT_ROUNDS |
/* round correctly FLT_ROUNDS = 2 or 3 */ |
if (sign) { |
- rv = -rv; |
+ rv.d = -rv.d; |
sign = 0; |
} |
#endif |
- /* rv = */ rounded_product(dval(rv), tens[e]); |
+ /* rv = */ rounded_product(dval(&rv), tens[e]); |
goto ret; |
#endif |
} |
@@ -1794,25 +2681,25 @@ strtod |
#ifdef Honor_FLT_ROUNDS |
/* round correctly FLT_ROUNDS = 2 or 3 */ |
if (sign) { |
- rv = -rv; |
+ rv.d = -rv.d; |
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; |
} |
@@ -1822,11 +2709,11 @@ strtod |
#ifdef Honor_FLT_ROUNDS |
/* round correctly FLT_ROUNDS = 2 or 3 */ |
if (sign) { |
- rv = -rv; |
+ rv.d = -rv.d; |
sign = 0; |
} |
#endif |
- /* rv = */ rounded_quotient(dval(rv), tens[-e]); |
+ /* rv = */ rounded_quotient(dval(&rv), tens[-e]); |
goto ret; |
} |
#endif |
@@ -1835,20 +2722,20 @@ strtod |
#ifdef IEEE_Arith |
#ifdef SET_INEXACT |
- inexact = 1; |
+ bc.inexact = 1; |
if (k <= DBL_DIG) |
oldinexact = get_inexact(); |
#endif |
#ifdef Avoid_Underflow |
- scale = 0; |
+ bc.scale = 0; |
#endif |
#ifdef Honor_FLT_ROUNDS |
- if (Rounding >= 2) { |
+ if (bc.rounding >= 2) { |
if (sign) |
- Rounding = Rounding == 2 ? 0 : 2; |
+ bc.rounding = bc.rounding == 2 ? 0 : 2; |
else |
- if (Rounding != 2) |
- Rounding = 0; |
+ if (bc.rounding != 2) |
+ bc.rounding = 0; |
} |
#endif |
#endif /*IEEE_Arith*/ |
@@ -1857,7 +2744,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: |
@@ -1867,103 +2754,99 @@ strtod |
/* Can't trust HUGE_VAL */ |
#ifdef IEEE_Arith |
#ifdef Honor_FLT_ROUNDS |
- switch(Rounding) { |
+ switch(bc.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) |
- scale = 2*P; |
+ bc.scale = 2*P; |
for(j = 0; e1 > 0; j++, e1 >>= 1) |
if (e1 & 1) |
- dval(rv) *= tinytens[j]; |
- if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) |
+ dval(&rv) *= tinytens[j]; |
+ if (bc.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. |
*/ |
@@ -1976,12 +2859,44 @@ strtod |
/* Put digits into bd: true value = bd * 10^e */ |
- bd0 = s2b(s0, nd0, nd, y); |
+ 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); |
for(;;) { |
bd = Balloc(bd0->k); |
Bcopy(bd, bd0); |
- bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ |
+ bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ |
bs = i2b(1); |
if (e >= 0) { |
@@ -1998,11 +2913,11 @@ strtod |
bd2 -= bbe; |
bs2 = bb2; |
#ifdef Honor_FLT_ROUNDS |
- if (Rounding != 1) |
+ if (bc.rounding != 1) |
bs2++; |
#endif |
#ifdef Avoid_Underflow |
- j = bbe - scale; |
+ j = bbe - bc.scale; |
i = j + bbbits - 1; /* logb(rv) */ |
if (i < Emin) /* denormal */ |
j += P - Emin; |
@@ -2027,7 +2942,7 @@ strtod |
bb2 += j; |
bd2 += j; |
#ifdef Avoid_Underflow |
- bd2 += scale; |
+ bd2 += bc.scale; |
#endif |
i = bb2 < bd2 ? bb2 : bd2; |
if (i > bs2) |
@@ -2052,99 +2967,116 @@ strtod |
if (bs2 > 0) |
bs = lshift(bs, bs2); |
delta = diff(bb, bd); |
- dsign = delta->sign; |
+ bc.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 (Rounding != 1) { |
+ 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 (i < 0) { |
/* Error is less than an ulp */ |
if (!delta->x[0] && delta->wds <= 1) { |
/* exact */ |
#ifdef SET_INEXACT |
- inexact = 0; |
+ bc.inexact = 0; |
#endif |
break; |
} |
- if (Rounding) { |
- if (dsign) { |
- adj = 1.; |
+ if (bc.rounding) { |
+ if (bc.dsign) { |
+ adj.d = 1.; |
goto apply_adj; |
} |
} |
- else if (!dsign) { |
- adj = -1.; |
- if (!word1(rv) |
- && !(word0(rv) & Frac_mask)) { |
- y = word0(rv) & Exp_mask; |
+ else if (!bc.dsign) { |
+ adj.d = -1.; |
+ if (!word1(&rv) |
+ && !(word0(&rv) & Frac_mask)) { |
+ y = word0(&rv) & Exp_mask; |
#ifdef Avoid_Underflow |
- if (!scale || y > 2*P*Exp_msk1) |
+ if (!bc.scale || y > 2*P*Exp_msk1) |
#else |
if (y) |
#endif |
{ |
delta = lshift(delta,Log2P); |
if (cmp(delta, bs) <= 0) |
- adj = -0.5; |
+ adj.d = -0.5; |
} |
} |
apply_adj: |
#ifdef Avoid_Underflow |
- if (scale && (y = word0(rv) & Exp_mask) |
+ if (bc.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*ulp(dval(rv)); |
- word0(rv) -= P*Exp_msk1; |
+ word0(&rv) += P*Exp_msk1; |
+ dval(&rv) += adj.d*ulp(dval(&rv)); |
+ word0(&rv) -= P*Exp_msk1; |
} |
else |
#endif /*Sudden_Underflow*/ |
#endif /*Avoid_Underflow*/ |
- dval(rv) += adj*ulp(dval(rv)); |
+ dval(&rv) += adj.d*ulp(&rv); |
} |
break; |
} |
- adj = ratio(delta, bs); |
- if (adj < 1.) |
- adj = 1.; |
- if (adj <= 0x7ffffffe) { |
+ adj.d = ratio(delta, bs); |
+ if (adj.d < 1.) |
+ adj.d = 1.; |
+ if (adj.d <= 0x7ffffffe) { |
/* adj = rounding ? ceil(adj) : floor(adj); */ |
- y = adj; |
- if (y != adj) { |
- if (!((Rounding>>1) ^ dsign)) |
+ y = adj.d; |
+ if (y != adj.d) { |
+ if (!((bc.rounding>>1) ^ bc.dsign)) |
y++; |
- adj = y; |
+ adj.d = y; |
} |
} |
#ifdef Avoid_Underflow |
- if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) |
- word0(adj) += (2*P+1)*Exp_msk1 - y; |
+ if (bc.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 *= ulp(dval(rv)); |
- if (dsign) |
- dval(rv) += adj; |
+ 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; |
else |
- dval(rv) -= adj; |
- word0(rv) -= P*Exp_msk1; |
+ dval(&rv) -= adj.d; |
+ word0(&rv) -= P*Exp_msk1; |
goto cont; |
} |
#endif /*Sudden_Underflow*/ |
#endif /*Avoid_Underflow*/ |
- adj *= ulp(dval(rv)); |
- if (dsign) { |
- if (word0(rv) == Big0 && word1(rv) == Big1) |
+ adj.d *= ulp(&rv); |
+ if (bc.dsign) { |
+ if (word0(&rv) == Big0 && word1(&rv) == Big1) |
goto ovfl; |
- dval(rv) += adj; |
+ dval(&rv) += adj.d; |
} |
else |
- dval(rv) -= adj; |
+ dval(&rv) -= adj.d; |
goto cont; |
} |
#endif /*Honor_FLT_ROUNDS*/ |
@@ -2153,25 +3085,25 @@ strtod |
/* Error is less than half an ulp -- check for |
* special case of mantissa a power of two. |
*/ |
- if (dsign || word1(rv) || word0(rv) & Bndry_mask |
+ if (bc.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) |
- inexact = 0; |
+ bc.inexact = 0; |
#endif |
break; |
} |
if (!delta->x[0] && delta->wds <= 1) { |
/* exact result */ |
#ifdef SET_INEXACT |
- inexact = 0; |
+ bc.inexact = 0; |
#endif |
break; |
} |
@@ -2182,62 +3114,72 @@ strtod |
} |
if (i == 0) { |
/* exactly half-way between */ |
- if (dsign) { |
- if ((word0(rv) & Bndry_mask1) == Bndry_mask1 |
- && word1(rv) == ( |
+ if (bc.dsign) { |
+ if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 |
+ && word1(&rv) == ( |
#ifdef Avoid_Underflow |
- (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) |
+ (bc.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 |
- dsign = 0; |
+ bc.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 <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) |
+ if (L <= (bc.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 (scale) { |
- L = word0(rv) & Exp_mask; |
+ if (bc.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 |
@@ -2245,32 +3187,42 @@ strtod |
#endif |
} |
#ifndef ROUND_BIASED |
- if (!(word1(rv) & LSB)) |
+ if (!(word1(&rv) & LSB)) |
break; |
#endif |
- if (dsign) |
- dval(rv) += ulp(dval(rv)); |
+ if (bc.dsign) |
+ dval(&rv) += ulp(&rv); |
#ifndef ROUND_BIASED |
else { |
- dval(rv) -= ulp(dval(rv)); |
+ dval(&rv) -= ulp(&rv); |
#ifndef Sudden_Underflow |
- if (!dval(rv)) |
+ if (!dval(&rv)) { |
+ if (bc.nd >nd) { |
+ bc.uflchk = 1; |
+ break; |
+ } |
goto undfl; |
+ } |
#endif |
} |
#ifdef Avoid_Underflow |
- dsign = 1 - dsign; |
+ bc.dsign = 1 - bc.dsign; |
#endif |
#endif |
break; |
} |
if ((aadj = ratio(delta, bs)) <= 2.) { |
- if (dsign) |
+ if (bc.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 (word1(&rv) == Tiny1 && !word0(&rv)) { |
+ if (bc.nd >nd) { |
+ bc.uflchk = 1; |
+ break; |
+ } |
goto undfl; |
+ } |
#endif |
aadj = 1.; |
aadj1 = -1.; |
@@ -2288,9 +3240,9 @@ strtod |
} |
else { |
aadj *= 0.5; |
- aadj1 = dsign ? aadj : -aadj; |
+ aadj1 = bc.dsign ? aadj : -aadj; |
#ifdef Check_FLT_ROUNDS |
- switch(Rounding) { |
+ switch(bc.rounding) { |
case 2: /* towards +infinity */ |
aadj1 -= 0.5; |
break; |
@@ -2303,65 +3255,72 @@ 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 = aadj1 * ulp(dval(rv)); |
- dval(rv) += adj; |
- if ((word0(rv) & Exp_mask) >= |
+ dval(&rv0) = dval(&rv); |
+ word0(&rv) -= P*Exp_msk1; |
+ adj.d = aadj1 * ulp(&rv); |
+ dval(&rv) += adj.d; |
+ 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 (scale && y <= 2*P*Exp_msk1) { |
+ if (bc.scale && y <= 2*P*Exp_msk1) { |
if (aadj <= 0x7fffffff) { |
if ((z = aadj) <= 0) |
z = 1; |
aadj = z; |
- aadj1 = dsign ? aadj : -aadj; |
+ aadj1 = bc.dsign ? aadj : -aadj; |
} |
- word0(aadj1) += (2*P+1)*Exp_msk1 - y; |
+ dval(&aadj2) = aadj1; |
+ word0(&aadj2) += (2*P+1)*Exp_msk1 - y; |
+ aadj1 = dval(&aadj2); |
} |
- adj = aadj1 * ulp(dval(rv)); |
- dval(rv) += adj; |
+ adj.d = aadj1 * ulp(&rv); |
+ dval(&rv) += adj.d; |
#else |
#ifdef Sudden_Underflow |
- 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; |
+ 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; |
#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 (word0(&rv0) == Tiny0 |
+ && word1(&rv0) == Tiny1) { |
+ if (bc.nd >nd) { |
+ bc.uflchk = 1; |
+ break; |
+ } |
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 = aadj1 * ulp(dval(rv)); |
- dval(rv) += adj; |
+ adj.d = aadj1 * ulp(&rv); |
+ dval(&rv) += adj.d; |
} |
#else /*Sudden_Underflow*/ |
/* Compute adj so that the IEEE rounding rules will |
@@ -2373,31 +3332,33 @@ strtod |
*/ |
if (y <= (P-1)*Exp_msk1 && aadj > 1.) { |
aadj1 = (double)(int)(aadj + 0.5); |
- if (!dsign) |
+ if (!bc.dsign) |
aadj1 = -aadj1; |
} |
- adj = aadj1 * ulp(dval(rv)); |
- dval(rv) += adj; |
+ adj.d = aadj1 * ulp(&rv); |
+ dval(&rv) += adj.d; |
#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 (!scale) |
+ if (!bc.scale) |
#endif |
if (y == z) { |
/* Can we stop now? */ |
L = (Long)aadj; |
aadj -= L; |
/* The tolerances below are conservative. */ |
- if (dsign || word1(rv) || word0(rv) & Bndry_mask) { |
+ if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { |
if (aadj < .4999999 || aadj > .5000001) |
break; |
} |
else if (aadj < .4999999/FLT_RADIX) |
break; |
} |
+ } |
#endif |
cont: |
Bfree(bb); |
@@ -2405,168 +3366,53 @@ 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 (inexact) { |
+ if (bc.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 (scale) { |
- word0(rv0) = Exp_1 - 2*P*Exp_msk1; |
- word1(rv0) = 0; |
- dval(rv) *= dval(rv0); |
+ if (bc.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 (inexact && !(word0(rv) & Exp_mask)) { |
+ if (bc.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); |
- } |
- |
- 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; |
+ return sign ? -dval(&rv) : dval(&rv); |
} |
#ifndef MULTIPLE_THREADS |
@@ -2671,10 +3517,10 @@ freedtoa(char *s) |
char * |
dtoa |
#ifdef KR_headers |
- (d, mode, ndigits, decpt, sign, rve) |
- double d; int mode, ndigits, *decpt, *sign; char **rve; |
+ (dd, mode, ndigits, decpt, sign, rve) |
+ double dd; int mode, ndigits, *decpt, *sign; char **rve; |
#else |
- (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) |
+ (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) |
#endif |
{ |
/* Arguments ndigits, decpt, sign are similar to those |
@@ -2711,7 +3557,7 @@ dtoa |
to hold the suppressed trailing zeros. |
*/ |
- int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, |
+ int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, |
j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, |
spec_case, try_quick; |
Long L; |
@@ -2720,7 +3566,8 @@ dtoa |
ULong x; |
#endif |
Bigint *b, *b1, *delta, *mlo, *mhi, *S; |
- double d2, ds, eps; |
+ U d2, eps, u; |
+ double ds; |
char *s, *s0; |
#ifdef SET_INEXACT |
int inexact, oldinexact; |
@@ -2746,34 +3593,35 @@ dtoa |
} |
#endif |
- if (word0(d) & Sign_bit) { |
+ u.d = dd; |
+ if (word0(&u) & Sign_bit) { |
/* set sign for everything, including 0's and NaNs */ |
*sign = 1; |
- word0(d) &= ~Sign_bit; /* clear sign bit */ |
+ word0(&u) &= ~Sign_bit; /* clear sign bit */ |
} |
else |
*sign = 0; |
#if defined(IEEE_Arith) + defined(VAX) |
#ifdef IEEE_Arith |
- if ((word0(d) & Exp_mask) == Exp_mask) |
+ if ((word0(&u) & Exp_mask) == Exp_mask) |
#else |
- if (word0(d) == 0x8000) |
+ if (word0(&u) == 0x8000) |
#endif |
{ |
/* Infinity or NaN */ |
*decpt = 9999; |
#ifdef IEEE_Arith |
- if (!word1(d) && !(word0(d) & 0xfffff)) |
+ if (!word1(&u) && !(word0(&u) & 0xfffff)) |
return nrv_alloc("Infinity", rve, 8); |
#endif |
return nrv_alloc("NaN", rve, 3); |
} |
#endif |
#ifdef IBM |
- dval(d) += 0; /* normalize */ |
+ dval(&u) += 0; /* normalize */ |
#endif |
- if (!dval(d)) { |
+ if (!dval(&u)) { |
*decpt = 1; |
return nrv_alloc("0", rve, 1); |
} |
@@ -2792,18 +3640,18 @@ dtoa |
} |
#endif |
- b = d2b(dval(d), &be, &bbits); |
+ b = d2b(&u, &be, &bbits); |
#ifdef Sudden_Underflow |
- i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); |
+ i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); |
#else |
- if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { |
+ if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { |
#endif |
- dval(d2) = dval(d); |
- word0(d2) &= Frac_mask1; |
- word0(d2) |= Exp_11; |
+ dval(&d2) = dval(&u); |
+ 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 |
@@ -2840,21 +3688,21 @@ dtoa |
/* d is denormalized */ |
i = bbits + be + (Bias + (P-1) - 1); |
- 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 */ |
+ 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 */ |
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(d) < tens[k]) |
+ if (dval(&u) < tens[k]) |
k--; |
k_check = 0; |
} |
@@ -2893,10 +3741,11 @@ 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; |
@@ -2930,7 +3779,7 @@ dtoa |
/* Try to get by with floating-point arithmetic. */ |
i = 0; |
- dval(d2) = dval(d); |
+ dval(&d2) = dval(&u); |
k0 = k; |
ilim0 = ilim; |
ieps = 2; /* conservative */ |
@@ -2940,7 +3789,7 @@ dtoa |
if (j & Bletch) { |
/* prevent overflows */ |
j &= Bletch - 1; |
- dval(d) /= bigtens[n_bigtens-1]; |
+ dval(&u) /= bigtens[n_bigtens-1]; |
ieps++; |
} |
for(; j; j >>= 1, i++) |
@@ -2948,32 +3797,32 @@ dtoa |
ieps++; |
ds *= bigtens[i]; |
} |
- dval(d) /= ds; |
+ dval(&u) /= ds; |
} |
else if ((j1 = -k)) { |
- dval(d) *= tens[j1 & 0xf]; |
+ dval(&u) *= tens[j1 & 0xf]; |
for(j = j1 >> 4; j; j >>= 1, i++) |
if (j & 1) { |
ieps++; |
- dval(d) *= bigtens[i]; |
+ dval(&u) *= bigtens[i]; |
} |
} |
- if (k_check && dval(d) < 1. && ilim > 0) { |
+ if (k_check && dval(&u) < 1. && ilim > 0) { |
if (ilim1 <= 0) |
goto fast_failed; |
ilim = ilim1; |
k--; |
- dval(d) *= 10.; |
+ dval(&u) *= 10.; |
ieps++; |
} |
- dval(eps) = ieps*dval(d) + 7.; |
- word0(eps) -= (P-1)*Exp_msk1; |
+ dval(&eps) = ieps*dval(&u) + 7.; |
+ word0(&eps) -= (P-1)*Exp_msk1; |
if (ilim == 0) { |
S = mhi = 0; |
- dval(d) -= 5.; |
- if (dval(d) > dval(eps)) |
+ dval(&u) -= 5.; |
+ if (dval(&u) > dval(&eps)) |
goto one_digit; |
- if (dval(d) < -dval(eps)) |
+ if (dval(&u) < -dval(&eps)) |
goto no_digits; |
goto fast_failed; |
} |
@@ -2982,34 +3831,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(d); |
- dval(d) -= L; |
+ L = dval(&u); |
+ dval(&u) -= L; |
*s++ = '0' + (int)L; |
- if (dval(d) < dval(eps)) |
+ if (dval(&u) < dval(&eps)) |
goto ret1; |
- if (1. - dval(d) < dval(eps)) |
+ if (1. - dval(&u) < dval(&eps)) |
goto bump_up; |
if (++i >= ilim) |
break; |
- dval(eps) *= 10.; |
- dval(d) *= 10.; |
+ dval(&eps) *= 10.; |
+ dval(&u) *= 10.; |
} |
} |
else { |
#endif |
/* Generate ilim digits, then fix them up. */ |
- dval(eps) *= tens[ilim-1]; |
- for(i = 1;; i++, dval(d) *= 10.) { |
- L = (Long)(dval(d)); |
- if (!(dval(d) -= L)) |
+ dval(&eps) *= tens[ilim-1]; |
+ for(i = 1;; i++, dval(&u) *= 10.) { |
+ L = (Long)(dval(&u)); |
+ if (!(dval(&u) -= L)) |
ilim = i; |
*s++ = '0' + (int)L; |
if (i == ilim) { |
- if (dval(d) > 0.5 + dval(eps)) |
+ if (dval(&u) > 0.5 + dval(&eps)) |
goto bump_up; |
- else if (dval(d) < 0.5 - dval(eps)) { |
+ else if (dval(&u) < 0.5 - dval(&eps)) { |
while(*--s == '0'); |
s++; |
goto ret1; |
@@ -3022,7 +3871,7 @@ dtoa |
#endif |
fast_failed: |
s = s0; |
- dval(d) = dval(d2); |
+ dval(&u) = dval(&d2); |
k = k0; |
ilim = ilim0; |
} |
@@ -3034,22 +3883,22 @@ dtoa |
ds = tens[k]; |
if (ndigits < 0 && ilim <= 0) { |
S = mhi = 0; |
- if (ilim < 0 || dval(d) <= 5*ds) |
+ if (ilim < 0 || dval(&u) <= 5*ds) |
goto no_digits; |
goto one_digit; |
} |
- for(i = 1;; i++, dval(d) *= 10.) { |
- L = (Long)(dval(d) / ds); |
- dval(d) -= L*ds; |
+ for(i = 1;; i++, dval(&u) *= 10.) { |
+ L = (Long)(dval(&u) / ds); |
+ dval(&u) -= L*ds; |
#ifdef Check_FLT_ROUNDS |
/* If FLT_ROUNDS == 2, L will usually be high by 1 */ |
- if (dval(d) < 0) { |
+ if (dval(&u) < 0) { |
L--; |
- dval(d) += ds; |
+ dval(&u) += ds; |
} |
#endif |
*s++ = '0' + (int)L; |
- if (!dval(d)) { |
+ if (!dval(&u)) { |
#ifdef SET_INEXACT |
inexact = 0; |
#endif |
@@ -3063,8 +3912,8 @@ dtoa |
case 2: goto bump_up; |
} |
#endif |
- dval(d) += dval(d); |
- if (dval(d) > ds || dval(d) == ds && L & 1) { |
+ dval(&u) += dval(&u); |
+ if (dval(&u) > ds || (dval(&u) == ds && L & 1)) { |
bump_up: |
while(*--s == '9') |
if (s == s0) { |
@@ -3129,9 +3978,9 @@ dtoa |
&& Rounding == 1 |
#endif |
) { |
- if (!word1(d) && !(word0(d) & Bndry_mask) |
+ if (!word1(&u) && !(word0(&u) & Bndry_mask) |
#ifndef Sudden_Underflow |
- && word0(d) & (Exp_mask & ~Exp_msk1) |
+ && word0(&u) & (Exp_mask & ~Exp_msk1) |
#endif |
) { |
/* The special case */ |
@@ -3151,22 +4000,16 @@ 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 |
- if (i > 4) { |
- i -= 4; |
- b2 += i; |
- m2 += i; |
- s2 += i; |
- } |
- else if (i < 4) { |
- i += 28; |
- b2 += i; |
- m2 += i; |
- s2 += i; |
- } |
+ i = dshift(S, s2); |
+ b2 += i; |
+ m2 += i; |
+ s2 += i; |
if (b2 > 0) |
b = lshift(b, b2); |
if (s2 > 0) |
@@ -3217,7 +4060,7 @@ dtoa |
j1 = delta->sign ? 1 : cmp(b, delta); |
Bfree(delta); |
#ifndef ROUND_BIASED |
- if (j1 == 0 && mode != 1 && !(word1(d) & 1) |
+ if (j1 == 0 && mode != 1 && !(word1(&u) & 1) |
#ifdef Honor_FLT_ROUNDS |
&& Rounding >= 1 |
#endif |
@@ -3234,11 +4077,11 @@ dtoa |
goto ret; |
} |
#endif |
- if (j < 0 || j == 0 && mode != 1 |
+ if (j < 0 || (j == 0 && mode != 1 |
#ifndef ROUND_BIASED |
- && !(word1(d) & 1) |
+ && !(word1(&u) & 1) |
#endif |
- ) { |
+ )) { |
if (!b->x[0] && b->wds <= 1) { |
#ifdef SET_INEXACT |
inexact = 0; |
@@ -3255,7 +4098,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; |
} |
@@ -3315,7 +4158,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) { |
@@ -3343,9 +4186,9 @@ dtoa |
#ifdef SET_INEXACT |
if (inexact) { |
if (!oldinexact) { |
- word0(d) = Exp_1 + (70 << Exp_shift); |
- word1(d) = 0; |
- dval(d) += 1.; |
+ word0(&u) = Exp_1 + (70 << Exp_shift); |
+ word1(&u) = 0; |
+ dval(&u) += 1.; |
} |
} |
else if (!oldinexact) |