diff options
author | Martynas Venckus <martynas@cvs.openbsd.org> | 2011-07-02 18:03:44 +0000 |
---|---|---|
committer | Martynas Venckus <martynas@cvs.openbsd.org> | 2011-07-02 18:03:44 +0000 |
commit | fafda69fce7f6c746719efdb813b7727c2c836b3 (patch) | |
tree | 1442e2124a15c78bc39b17f1b8948e1b2fe4331c /lib/libc | |
parent | 5f1fa926488fbe7894ea95be3e160ad69d769a73 (diff) |
Rebase on gdtoa-20110428; contains fixes for absurdly long inputs
(among other things). Fixes mozilla crasher for the link i was
provided with.
With the massive local changes to teach that malloc can fail, fixes
for the vax, strlcpy, moving things to library namespaces. Tested
on all architectures.
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gdtoa/dmisc.c | 6 | ||||
-rw-r--r-- | lib/libc/gdtoa/dtoa.c | 190 | ||||
-rw-r--r-- | lib/libc/gdtoa/gdtoa.c | 192 | ||||
-rw-r--r-- | lib/libc/gdtoa/gdtoa.h | 22 | ||||
-rw-r--r-- | lib/libc/gdtoa/gdtoaimp.h | 75 | ||||
-rw-r--r-- | lib/libc/gdtoa/gethex.c | 20 | ||||
-rw-r--r-- | lib/libc/gdtoa/hexnan.c | 6 | ||||
-rw-r--r-- | lib/libc/gdtoa/misc.c | 84 | ||||
-rw-r--r-- | lib/libc/gdtoa/smisc.c | 32 | ||||
-rw-r--r-- | lib/libc/gdtoa/strtod.c | 482 | ||||
-rw-r--r-- | lib/libc/gdtoa/strtodg.c | 172 | ||||
-rw-r--r-- | lib/libc/gdtoa/strtof.c | 4 | ||||
-rw-r--r-- | lib/libc/gdtoa/strtorx.c | 3 | ||||
-rw-r--r-- | lib/libc/gdtoa/ulp.c | 20 |
14 files changed, 696 insertions, 612 deletions
diff --git a/lib/libc/gdtoa/dmisc.c b/lib/libc/gdtoa/dmisc.c index 585cbfc9a56..a5795cfb79a 100644 --- a/lib/libc/gdtoa/dmisc.c +++ b/lib/libc/gdtoa/dmisc.c @@ -53,9 +53,9 @@ rv_alloc(int i) if (r == NULL) return ( #ifndef MULTIPLE_THREADS - dtoa_result = + dtoa_result = #endif - NULL); + NULL); *r = k; return #ifndef MULTIPLE_THREADS @@ -75,7 +75,7 @@ nrv_alloc(char *s, char **rve, int n) t = rv = rv_alloc(n); if (t == NULL) - return NULL; + return (NULL); while((*t = *s++) !=0) t++; if (rve) diff --git a/lib/libc/gdtoa/dtoa.c b/lib/libc/gdtoa/dtoa.c index 89ab53137b2..668f7b50b2d 100644 --- a/lib/libc/gdtoa/dtoa.c +++ b/lib/libc/gdtoa/dtoa.c @@ -75,10 +75,10 @@ THIS SOFTWARE. char * dtoa #ifdef KR_headers - (d, mode, ndigits, decpt, sign, rve) - double d; int mode, ndigits, *decpt, *sign; char **rve; + (d0, mode, ndigits, decpt, sign, rve) + double d0; int mode, ndigits, *decpt, *sign; char **rve; #else - (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) + (double d0, int mode, int ndigits, int *decpt, int *sign, char **rve) #endif { /* Arguments ndigits, decpt, sign are similar to those @@ -124,7 +124,8 @@ dtoa ULong x; #endif Bigint *b, *b1, *delta, *mlo, *mhi, *S; - double d2, ds, eps; + U d, d2, eps; + double ds; char *s, *s0; #ifdef SET_INEXACT int inexact, oldinexact; @@ -149,35 +150,35 @@ dtoa dtoa_result = 0; } #endif - - if (word0(d) & Sign_bit) { + d.d = d0; + if (word0(&d) & Sign_bit) { /* set sign for everything, including 0's and NaNs */ *sign = 1; - word0(d) &= ~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(d) & Exp_mask) == Exp_mask) + if ((word0(&d) & Exp_mask) == Exp_mask) #else - if (word0(d) == 0x8000) + if (word0(&d) == 0x8000) #endif { /* Infinity or NaN */ *decpt = 9999; #ifdef IEEE_Arith - if (!word1(d) && !(word0(d) & 0xfffff)) + if (!word1(&d) && !(word0(&d) & 0xfffff)) return nrv_alloc("Infinity", rve, 8); #endif return nrv_alloc("NaN", rve, 3); } #endif #ifdef IBM - dval(d) += 0; /* normalize */ + dval(&d) += 0; /* normalize */ #endif - if (!dval(d)) { + if (!dval(&d)) { *decpt = 1; return nrv_alloc("0", rve, 1); } @@ -196,28 +197,28 @@ dtoa } #endif - b = d2b(dval(d), &be, &bbits); + b = d2b(dval(&d), &be, &bbits); if (b == NULL) - return NULL; + return (NULL); #ifdef Sudden_Underflow - i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); + i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); #else - if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { + if (( i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { #endif - dval(d2) = dval(d); - 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) )!=0) - dval(d2) /= 1 << j; + if (( j = 11 - hi0bits(word0(&d2) & Frac_mask) )!=0) + dval(&d2) /= 1 << j; #endif /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * log10(&d) = (i-Bias)*log(2)/log(10) + log10(&d2) * - * This suggests computing an approximation k to log10(d) by + * This suggests computing an approximation k to log10(&d) by * * k = (i - Bias)*0.301029995663981 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); @@ -246,21 +247,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(&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(d) < tens[k]) + if (dval(&d) < tens[k]) k--; k_check = 0; } @@ -299,10 +300,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; @@ -338,7 +340,7 @@ dtoa /* Try to get by with floating-point arithmetic. */ i = 0; - dval(d2) = dval(d); + dval(&d2) = dval(&d); k0 = k; ilim0 = ilim; ieps = 2; /* conservative */ @@ -348,7 +350,7 @@ dtoa if (j & Bletch) { /* prevent overflows */ j &= Bletch - 1; - dval(d) /= bigtens[n_bigtens-1]; + dval(&d) /= bigtens[n_bigtens-1]; ieps++; } for(; j; j >>= 1, i++) @@ -356,32 +358,32 @@ dtoa ieps++; ds *= bigtens[i]; } - dval(d) /= ds; + dval(&d) /= ds; } else if (( j1 = -k )!=0) { - dval(d) *= tens[j1 & 0xf]; + dval(&d) *= tens[j1 & 0xf]; for(j = j1 >> 4; j; j >>= 1, i++) if (j & 1) { ieps++; - dval(d) *= bigtens[i]; + dval(&d) *= bigtens[i]; } } - if (k_check && dval(d) < 1. && ilim > 0) { + if (k_check && dval(&d) < 1. && ilim > 0) { if (ilim1 <= 0) goto fast_failed; ilim = ilim1; k--; - dval(d) *= 10.; + dval(&d) *= 10.; ieps++; } - dval(eps) = ieps*dval(d) + 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(d) -= 5.; - if (dval(d) > dval(eps)) + dval(&d) -= 5.; + if (dval(&d) > dval(&eps)) goto one_digit; - if (dval(d) < -dval(eps)) + if (dval(&d) < -dval(&eps)) goto no_digits; goto fast_failed; } @@ -390,34 +392,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(&d); + dval(&d) -= L; *s++ = '0' + (int)L; - if (dval(d) < dval(eps)) + if (dval(&d) < dval(&eps)) goto ret1; - if (1. - dval(d) < dval(eps)) + if (1. - dval(&d) < dval(&eps)) goto bump_up; if (++i >= ilim) break; - dval(eps) *= 10.; - dval(d) *= 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(d) *= 10.) { - L = (Long)(dval(d)); - if (!(dval(d) -= 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(d) > 0.5 + dval(eps)) + if (dval(&d) > 0.5 + dval(&eps)) goto bump_up; - else if (dval(d) < 0.5 - dval(eps)) { + else if (dval(&d) < 0.5 - dval(&eps)) { while(*--s == '0'); s++; goto ret1; @@ -430,7 +432,7 @@ dtoa #endif fast_failed: s = s0; - dval(d) = dval(d2); + dval(&d) = dval(&d2); k = k0; ilim = ilim0; } @@ -442,22 +444,22 @@ dtoa ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = 0; - if (ilim < 0 || dval(d) <= 5*ds) + if (ilim < 0 || dval(&d) <= 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(&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(d) < 0) { + if (dval(&d) < 0) { L--; - dval(d) += ds; + dval(&d) += ds; } #endif *s++ = '0' + (int)L; - if (!dval(d)) { + if (!dval(&d)) { #ifdef SET_INEXACT inexact = 0; #endif @@ -471,8 +473,13 @@ dtoa case 2: goto bump_up; } #endif - dval(d) += dval(d); - if (dval(d) > ds || dval(d) == ds && L & 1) { + dval(&d) += dval(&d); +#ifdef ROUND_BIASED + if (dval(&d) >= ds) +#else + if (dval(&d) > ds || (dval(&d) == ds && L & 1)) +#endif + { bump_up: while(*--s == '9') if (s == s0) { @@ -529,13 +536,13 @@ dtoa b = pow5mult(b, j); if (b == NULL) return (NULL); - } + } } else { b = pow5mult(b, b5); if (b == NULL) return (NULL); - } + } } S = i2b(1); if (S == NULL) @@ -544,7 +551,7 @@ dtoa S = pow5mult(S, s5); if (S == NULL) return (NULL); - } + } /* Check for special case that d is a normalized power of 2. */ @@ -554,9 +561,9 @@ dtoa && Rounding == 1 #endif ) { - if (!word1(d) && !(word0(d) & Bndry_mask) + if (!word1(&d) && !(word0(&d) & Bndry_mask) #ifndef Sudden_Underflow - && word0(d) & (Exp_mask & ~Exp_msk1) + && word0(&d) & (Exp_mask & ~Exp_msk1) #endif ) { /* The special case */ @@ -596,12 +603,12 @@ dtoa b = lshift(b, b2); if (b == NULL) return (NULL); - } + } if (s2 > 0) { S = lshift(S, s2); if (S == NULL) return (NULL); - } + } if (k_check) { if (cmp(b,S) < 0) { k--; @@ -612,15 +619,15 @@ dtoa mhi = multadd(mhi, 10, 0); if (mhi == NULL) return (NULL); - } + } ilim = ilim1; } } if (ilim <= 0 && (mode == 3 || mode == 5)) { - S = multadd(S, 5, 0); + S = multadd(S,5,0); if (S == NULL) return (NULL); - if (ilim < 0 || cmp(b, S) <= 0) { + if (ilim < 0 || cmp(b,S) <= 0) { /* no digits, fcvt style */ no_digits: k = -1 - ndigits; @@ -636,7 +643,7 @@ dtoa mhi = lshift(mhi, m2); if (mhi == NULL) return (NULL); - } + } /* Compute mlo -- check for special case * that d is a normalized power of 2. @@ -665,7 +672,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(&d) & 1) #ifdef Honor_FLT_ROUNDS && Rounding >= 1 #endif @@ -682,11 +689,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(&d) & 1) #endif - ) { + )) { if (!b->x[0] && b->wds <= 1) { #ifdef SET_INEXACT inexact = 0; @@ -705,7 +712,11 @@ dtoa if (b == NULL) return (NULL); j1 = cmp(b, S); - if ((j1 > 0 || j1 == 0 && dig & 1) +#ifdef ROUND_BIASED + if (j1 >= 0 /*)*/ +#else + if ((j1 > 0 || (j1 == 0 && dig & 1)) +#endif && dig++ == '9') goto round_9_up; } @@ -739,7 +750,7 @@ dtoa mlo = mhi = multadd(mhi, 10, 0); if (mlo == NULL) return (NULL); - } + } else { mlo = multadd(mlo, 10, 0); if (mlo == NULL) @@ -778,7 +789,12 @@ dtoa if (b == NULL) return (NULL); j = cmp(b, S); - if (j > 0 || j == 0 && dig & 1) { +#ifdef ROUND_BIASED + if (j >= 0) +#else + if (j > 0 || (j == 0 && dig & 1)) +#endif + { roundoff: while(*--s == '9') if (s == s0) { @@ -789,7 +805,9 @@ dtoa ++*s++; } else { +#ifdef Honor_FLT_ROUNDS trimzeros: +#endif while(*--s == '0'); s++; } @@ -804,9 +822,9 @@ dtoa #ifdef SET_INEXACT if (inexact) { if (!oldinexact) { - word0(d) = Exp_1 + (70 << Exp_shift); - word1(d) = 0; - dval(d) += 1.; + word0(&d) = Exp_1 + (70 << Exp_shift); + word1(&d) = 0; + dval(&d) += 1.; } } else if (!oldinexact) diff --git a/lib/libc/gdtoa/gdtoa.c b/lib/libc/gdtoa/gdtoa.c index 33c5adf4c48..fd11de56001 100644 --- a/lib/libc/gdtoa/gdtoa.c +++ b/lib/libc/gdtoa/gdtoa.c @@ -125,6 +125,7 @@ gdtoa the returned string. If not null, *rve is set to point to the end of the return value. If d is +-Infinity or NaN, then *decpt is set to 9999. + be = exponent: value = (integer represented by bits) * (2 to the power of be). mode: 0 ==> shortest string that yields d when read in @@ -159,8 +160,9 @@ gdtoa int rdir, s2, s5, spec_case, try_quick; Long L; Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S; - double d, d2, ds, eps; + double d2, ds; char *s, *s0; + U d, eps; #ifndef MULTIPLE_THREADS if (dtoa_result) { @@ -201,21 +203,21 @@ gdtoa return nrv_alloc("0", rve, 1); } - dval(d) = b2d(b, &i); + dval(&d) = b2d(b, &i); i = be + bbits - 1; - word0(d) &= Frac_mask1; - word0(d) |= Exp_11; + word0(&d) &= Frac_mask1; + word0(&d) |= Exp_11; #ifdef IBM - if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) - dval(d) /= 1 << j; + if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0) + dval(&d) /= 1 << j; #endif /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * log10(&d) = (i-Bias)*log(2)/log(10) + log10(d2) * - * This suggests computing an approximation k to log10(d) by + * This suggests computing an approximation k to log10(&d) by * * k = (i - Bias)*0.301029995663981 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); @@ -235,7 +237,7 @@ gdtoa i <<= 2; i += j; #endif - ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + ds = (dval(&d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; /* correct assumption about exponent range */ if ((j = i) < 0) @@ -250,13 +252,13 @@ gdtoa #ifdef IBM j = be + bbits - 1; if ( (j1 = j & 3) !=0) - dval(d) *= 1 << j1; - word0(d) += j << Exp_shift - 2 & Exp_mask; + dval(&d) *= 1 << j1; + word0(&d) += j << Exp_shift - 2 & Exp_mask; #else - word0(d) += (be + bbits - 1) << Exp_shift; + word0(&d) += (be + bbits - 1) << Exp_shift; #endif if (k >= 0 && k <= Ten_pmax) { - if (dval(d) < tens[k]) + if (dval(&d) < tens[k]) k--; k_check = 0; } @@ -286,11 +288,14 @@ gdtoa mode -= 4; try_quick = 0; } + else if (i >= -4 - Emin || i < Emin) + 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 = (int)(nbits * .30103) + 3; ndigits = 0; break; @@ -334,10 +339,10 @@ gdtoa /* Try to get by with floating-point arithmetic. */ i = 0; - d2 = dval(d); + d2 = dval(&d); #ifdef IBM - if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) - dval(d) /= 1 << j; + if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0) + dval(&d) /= 1 << j; #endif k0 = k; ilim0 = ilim; @@ -348,7 +353,7 @@ gdtoa if (j & Bletch) { /* prevent overflows */ j &= Bletch - 1; - dval(d) /= bigtens[n_bigtens-1]; + dval(&d) /= bigtens[n_bigtens-1]; ieps++; } for(; j; j >>= 1, i++) @@ -360,30 +365,30 @@ gdtoa else { ds = 1.; if ( (j1 = -k) !=0) { - dval(d) *= tens[j1 & 0xf]; + dval(&d) *= tens[j1 & 0xf]; for(j = j1 >> 4; j; j >>= 1, i++) if (j & 1) { ieps++; - dval(d) *= bigtens[i]; + dval(&d) *= bigtens[i]; } } } - if (k_check && dval(d) < 1. && ilim > 0) { + if (k_check && dval(&d) < 1. && ilim > 0) { if (ilim1 <= 0) goto fast_failed; ilim = ilim1; k--; - dval(d) *= 10.; + dval(&d) *= 10.; ieps++; } - dval(eps) = ieps*dval(d) + 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(d) -= 5.; - if (dval(d) > dval(eps)) + dval(&d) -= 5.; + if (dval(&d) > dval(&eps)) goto one_digit; - if (dval(d) < -dval(eps)) + if (dval(&d) < -dval(&eps)) goto no_digits; goto fast_failed; } @@ -392,38 +397,38 @@ gdtoa /* Use Steele & White method of only * generating digits needed. */ - dval(eps) = ds*0.5/tens[ilim-1] - dval(eps); + dval(&eps) = ds*0.5/tens[ilim-1] - dval(&eps); for(i = 0;;) { - L = (Long)(dval(d)/ds); - dval(d) -= L*ds; + L = (Long)(dval(&d)/ds); + dval(&d) -= L*ds; *s++ = '0' + (int)L; - if (dval(d) < dval(eps)) { - if (dval(d)) + if (dval(&d) < dval(&eps)) { + if (dval(&d)) inex = STRTOG_Inexlo; goto ret1; } - if (ds - dval(d) < dval(eps)) + if (ds - dval(&d) < dval(&eps)) goto bump_up; if (++i >= ilim) break; - dval(eps) *= 10.; - dval(d) *= 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(d) *= 10.) { - if ( (L = (Long)(dval(d)/ds)) !=0) - dval(d) -= L*ds; + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&d) *= 10.) { + if ( (L = (Long)(dval(&d)/ds)) !=0) + dval(&d) -= L*ds; *s++ = '0' + (int)L; if (i == ilim) { ds *= 0.5; - if (dval(d) > ds + dval(eps)) + if (dval(&d) > ds + dval(&eps)) goto bump_up; - else if (dval(d) < ds - dval(eps)) { - if (dval(d)) + else if (dval(&d) < ds - dval(&eps)) { + if (dval(&d)) inex = STRTOG_Inexlo; goto clear_trailing0; } @@ -435,7 +440,7 @@ gdtoa #endif fast_failed: s = s0; - dval(d) = d2; + dval(&d) = d2; k = k0; ilim = ilim0; } @@ -447,22 +452,22 @@ gdtoa ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = 0; - if (ilim < 0 || dval(d) <= 5*ds) + if (ilim < 0 || dval(&d) <= 5*ds) goto no_digits; goto one_digit; } - for(i = 1;; i++, dval(d) *= 10.) { - L = dval(d) / ds; - dval(d) -= L*ds; + for(i = 1;; i++, dval(&d) *= 10.) { + L = dval(&d) / ds; + dval(&d) -= L*ds; #ifdef Check_FLT_ROUNDS /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(d) < 0) { + if (dval(&d) < 0) { L--; - dval(d) += ds; + dval(&d) += ds; } #endif *s++ = '0' + (int)L; - if (dval(d) == 0.) + if (dval(&d) == 0.) break; if (i == ilim) { if (rdir) { @@ -471,8 +476,13 @@ gdtoa inex = STRTOG_Inexlo; goto ret1; } - dval(d) += dval(d); - if (dval(d) > ds || dval(d) == ds && L & 1) { + dval(&d) += dval(&d); +#ifdef ROUND_BIASED + if (dval(&d) >= ds) +#else + if (dval(&d) > ds || (dval(&d) == ds && L & 1)) +#endif + { bump_up: inex = STRTOG_Inexhi; while(*--s == '9') @@ -499,13 +509,15 @@ gdtoa m5 = b5; mhi = mlo = 0; if (leftright) { - if (mode < 2) { - i = nbits - bbits; - if (be - i++ < fpi->emin) - /* denormal */ - i = be - fpi->emin + 1; + i = nbits - bbits; + if (be - i++ < fpi->emin && mode != 3 && mode != 5) { + /* denormal */ + i = be - fpi->emin + 1; + if (mode >= 2 && ilim > 0 && ilim < i) + goto small_ilim; } - else { + else if (mode >= 2) { + small_ilim: j = ilim - 1; if (m5 >= j) m5 -= j; @@ -547,13 +559,13 @@ gdtoa b = pow5mult(b, j); if (b == NULL) return (NULL); - } + } } else { b = pow5mult(b, b5); if (b == NULL) return (NULL); - } + } } S = i2b(1); if (S == NULL) @@ -562,7 +574,7 @@ gdtoa S = pow5mult(S, s5); if (S == NULL) return (NULL); - } + } /* Check for special case that d is a normalized power of 2. */ @@ -583,35 +595,18 @@ gdtoa * and for all and pass them and a shift to quorem, so it * 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) !=0) - i = 32 - i; -#else - if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) !=0) - i = 16 - i; -#endif - 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) { + i = ((s5 ? hi0bits(S->x[S->wds-1]) : ULbits - 1) - s2 - 4) & kmask; + m2 += i; + if ((b2 += i) > 0) { b = lshift(b, b2); if (b == NULL) return (NULL); - } - if (s2 > 0) { + } + if ((s2 += i) > 0) { S = lshift(S, s2); if (S == NULL) return (NULL); - } + } if (k_check) { if (cmp(b,S) < 0) { k--; @@ -622,15 +617,15 @@ gdtoa mhi = multadd(mhi, 10, 0); if (mhi == NULL) return (NULL); - } + } ilim = ilim1; } } if (ilim <= 0 && mode > 2) { - S = multadd(S, 5, 0); + S = multadd(S,5,0); if (S == NULL) return (NULL); - if (ilim < 0 || cmp(b, S) <= 0) { + if (ilim < 0 || cmp(b,S) <= 0) { /* no digits, fcvt style */ no_digits: k = -1 - ndigits; @@ -648,7 +643,7 @@ gdtoa mhi = lshift(mhi, m2); if (mhi == NULL) return (NULL); - } + } /* Compute mlo -- check for special case * that d is a normalized power of 2. @@ -692,11 +687,11 @@ gdtoa goto ret; } #endif - if (j < 0 || j == 0 && !mode + if (j < 0 || (j == 0 && !mode #ifndef ROUND_BIASED && !(bits[0] & 1) #endif - ) { + )) { if (rdir && (b->wds > 1 || b->x[0])) { if (rdir == 2) { inex = STRTOG_Inexlo; @@ -725,7 +720,11 @@ gdtoa if (b == NULL) return (NULL); j1 = cmp(b, S); - if ((j1 > 0 || j1 == 0 && dig & 1) +#ifdef ROUND_BIASED + if (j1 >= 0 /*)*/ +#else + if ((j1 > 0 || (j1 == 0 && dig & 1)) +#endif && dig++ == '9') goto round_9_up; inex = STRTOG_Inexhi; @@ -757,7 +756,7 @@ gdtoa mlo = mhi = multadd(mhi, 10, 0); if (mlo == NULL) return (NULL); - } + } else { mlo = multadd(mlo, 10, 0); if (mlo == NULL) @@ -781,7 +780,7 @@ gdtoa /* Round off last digit */ if (rdir) { - if (rdir == 2 || b->wds <= 1 && !b->x[0]) + if (rdir == 2 || (b->wds <= 1 && !b->x[0])) goto chopzeros; goto roundoff; } @@ -789,7 +788,12 @@ gdtoa if (b == NULL) return (NULL); j = cmp(b, S); - if (j > 0 || j == 0 && dig & 1) { +#ifdef ROUND_BIASED + if (j >= 0) +#else + if (j > 0 || (j == 0 && dig & 1)) +#endif + { roundoff: inex = STRTOG_Inexhi; while(*--s == '9') diff --git a/lib/libc/gdtoa/gdtoa.h b/lib/libc/gdtoa/gdtoa.h index 664b77e0ef6..9e06233f27b 100644 --- a/lib/libc/gdtoa/gdtoa.h +++ b/lib/libc/gdtoa/gdtoa.h @@ -36,7 +36,7 @@ THIS SOFTWARE. #include <stddef.h> /* for size_t */ #ifndef Long -#define Long long +#define Long int #endif #ifndef ULong typedef unsigned Long ULong; @@ -71,17 +71,17 @@ typedef unsigned short UShort; STRTOG_NaN = 0x004, STRTOG_NaNbits = 0x005, STRTOG_NoNumber = 0x006, - STRTOG_NoMemory = 0x007, + STRTOG_NoMemory = 0x007, STRTOG_Retmask = 0x00f, /* The following may be or-ed into one of the above values. */ - STRTOG_Inexlo = 0x010, /* returned result rounded toward zero */ - STRTOG_Inexhi = 0x020, /* returned result rounded away from zero */ - STRTOG_Inexact = 0x030, - STRTOG_Underflow= 0x040, - STRTOG_Overflow = 0x080, - STRTOG_Neg = 0x100 /* does not affect STRTOG_Inexlo or - * STRTOG_Inexhi */ + + STRTOG_Neg = 0x010, /* does not affect STRTOG_Inexlo or STRTOG_Inexhi */ + STRTOG_Inexlo = 0x020, /* returned result rounded toward zero */ + STRTOG_Inexhi = 0x030, /* returned result rounded away from zero */ + STRTOG_Inexact = 0x040, + STRTOG_Underflow= 0x080, + STRTOG_Overflow = 0x100 }; typedef struct @@ -109,8 +109,8 @@ extern char* __dtoa ANSI((double d, int mode, int ndigits, int *decpt, extern char* __gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)); extern void __freedtoa ANSI((char*)); -extern float __strtof ANSI((CONST char *, char **)); -extern double __strtod ANSI((CONST char *, char **)); +extern float strtof ANSI((CONST char *, char **)); +extern double strtod ANSI((CONST char *, char **)); extern int __strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*)); extern char* __g_ddfmt ANSI((char*, double*, int, size_t)); diff --git a/lib/libc/gdtoa/gdtoaimp.h b/lib/libc/gdtoa/gdtoaimp.h index 4ece8801d37..7a36967ca58 100644 --- a/lib/libc/gdtoa/gdtoaimp.h +++ b/lib/libc/gdtoa/gdtoaimp.h @@ -89,12 +89,18 @@ THIS SOFTWARE. * #define IBM for IBM mainframe-style floating-point arithmetic. * #define VAX for VAX-style floating-point arithmetic (D_floating). * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. + * computation of dtoa and gdtoa. This will cause modes 4 and 5 to be + * treated the same as modes 2 and 3 for some inputs. * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines * that use extended-precision instructions to compute rounded * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define ROUND_BIASED for IEEE-format with biased rounding and arithmetic + * that rounds toward +Infinity. + * #define ROUND_BIASED_without_Round_Up for IEEE-format with biased + * rounding when the underlying floating-point arithmetic uses + * unbiased rounding. This prevent using ordinary floating-point + * arithmetic when the result could be computed with one rounding error. * #define Inaccurate_Divide for IEEE-format with correctly rounded * products but inaccurate quotients, e.g., for Intel i860. * #define NO_LONG_LONG on machines that do not have a "long long" @@ -113,7 +119,12 @@ THIS SOFTWARE. * #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 gdtoa call after a gdtoa 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, @@ -126,8 +137,10 @@ THIS SOFTWARE. * conversions of IEEE doubles in single-threaded executions with * 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with * 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate. - * #define INFNAN_CHECK on IEEE systems to cause strtod to check for - * Infinity and NaN (case insensitively). + * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK + * #defined automatically on IEEE systems. On such systems, + * when INFNAN_CHECK is #defined, strtod checks + * for Infinity and NaN (case insensitively). * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, * strtodg also accepts (case insensitively) strings of the form * NaN(x), where x is a string of hexadecimal digits (optionally @@ -160,19 +173,11 @@ THIS SOFTWARE. * #define NO_STRING_H to use private versions of memcpy. * On some K&R systems, it may also be necessary to * #define DECLARE_SIZE_T in this case. - * #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. */ #ifndef GDTOAIMP_H_INCLUDED #define GDTOAIMP_H_INCLUDED - -#define Long int - #include "gdtoa.h" #include "gd_qnan.h" #ifdef Honor_FLT_ROUNDS @@ -271,25 +276,14 @@ 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] -#else -#define word0(x) ((ULong *)&x)[0] -#define word1(x) ((ULong *)&x)[1] -#endif -#else /* !YES_ALIAS */ #ifdef IEEE_8087 -#define word0(x) ((U*)&x)->L[1] -#define word1(x) ((U*)&x)->L[0] +#define word0(x) (x)->L[1] +#define word1(x) (x)->L[0] #else -#define word0(x) ((U*)&x)->L[0] -#define word1(x) ((U*)&x)->L[1] +#define word0(x) (x)->L[0] +#define word1(x) (x)->L[1] #endif -#define dval(x) ((U*)&x)->d -#endif /* YES_ALIAS */ +#define dval(x) (x)->d /* The following definition of Storeinc is appropriate for MIPS processors. * An alternative that might be better on some machines is @@ -382,6 +376,7 @@ typedef union { double d; ULong L[2]; } U; #define Exp_mask 0x7f80 #define P 56 #define Bias 129 +#define Emin (-127) #define Exp_1 0x40800000 #define Exp_11 0x4080 #define Ebits 8 @@ -403,6 +398,11 @@ typedef union { double d; ULong L[2]; } U; #ifndef IEEE_Arith #define ROUND_BIASED +#else +#ifdef ROUND_BIASED_without_Round_Up +#undef ROUND_BIASED +#define ROUND_BIASED +#endif #endif #ifdef RND_PRODQUOT @@ -468,7 +468,7 @@ extern void *__dtoa_locks[]; #define FREE_DTOA_LOCK(n) _MUTEX_UNLOCK(&__dtoa_locks[n]) #endif -#define Kmax 15 +#define Kmax 9 struct Bigint { @@ -540,8 +540,8 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); #define gethex __gethex_D2A #define hexdig __hexdig_D2A #define hexnan __hexnan_D2A -#define hi0bits __hi0bits_D2A -#define hi0bits_D2A __hi0bits_D2A +#define hi0bits(x) __hi0bits_D2A((ULong)(x)) +#define hi0bits_D2A __hi0bits_D2A #define i2b __i2b_D2A #define increment __increment_D2A #define lo0bits __lo0bits_D2A @@ -559,6 +559,7 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); #define set_ones __set_ones_D2A #define strcp __strcp_D2A #define strtoIg __strtoIg_D2A +#define sulp __sulp_D2A #define sum __sum_D2A #define tens __tens_D2A #define tinytens __tinytens_D2A @@ -587,8 +588,6 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); extern Bigint *diff ANSI((Bigint*, Bigint*)); extern char *dtoa ANSI((double d, int mode, int ndigits, int *decpt, int *sign, char **rve)); - extern char *gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, - int mode, int ndigits, int *decpt, char **rve)); extern char *g__fmt ANSI((char*, char*, char*, int, ULong, size_t)); extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int)); extern void hexdig_init_D2A(Void); @@ -607,14 +606,14 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); extern double ratio ANSI((Bigint*, Bigint*)); extern void rshift ANSI((Bigint*, int)); extern char *rv_alloc ANSI((int)); - extern Bigint *s2b ANSI((CONST char*, int, int, ULong)); + extern Bigint *s2b ANSI((CONST char*, int, int, ULong, int)); extern Bigint *set_ones ANSI((Bigint*, int)); extern char *strcp ANSI((char*, const char*)); extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*)); extern double strtod ANSI((const char *s00, char **se)); extern Bigint *sum ANSI((Bigint*, Bigint*)); extern int trailz ANSI((Bigint*)); - extern double ulp ANSI((double)); + extern double ulp ANSI((U*)); #ifdef __cplusplus } @@ -629,6 +628,10 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) */ #ifdef IEEE_Arith +#ifndef NO_INFNAN_CHECK +#undef INFNAN_CHECK +#define INFNAN_CHECK +#endif #ifdef IEEE_MC68k #define _0 0 #define _1 1 diff --git a/lib/libc/gdtoa/gethex.c b/lib/libc/gdtoa/gethex.c index b13599ddbdf..7ace0fa4cd2 100644 --- a/lib/libc/gdtoa/gethex.c +++ b/lib/libc/gdtoa/gethex.c @@ -56,11 +56,9 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) const unsigned char *decimalpoint; static unsigned char *decimalpoint_cache; if (!(s0 = decimalpoint_cache)) { - size_t len; s0 = (unsigned char*)localeconv()->decimal_point; - len = strlen(s0) + 1; - if ((decimalpoint_cache = (char*)malloc(len))) { - strlcpy(decimalpoint_cache, s0, len); + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { + strlcpy(decimalpoint_cache, s0, strlen(s0) + 1); s0 = decimalpoint_cache; } } @@ -194,7 +192,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) ++n; for(j = n, k = 0; j >>= 1; ++k); *bp = b = Balloc(k); - if (b == NULL) + if (*bp == NULL) return (STRTOG_NoMemory); b->wds = n; for(j = 0; j < n0; ++j) @@ -205,7 +203,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) return STRTOG_Normal | STRTOG_Inexlo; } n = s1 - s0 - 1; - for(k = 0; n > 7; n >>= 1) + for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) k++; b = Balloc(k); if (b == NULL) @@ -226,7 +224,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) if (*--s1 == '.') continue; #endif - if (n == 32) { + if (n == ULbits) { *x++ = L; L = 0; n = 0; @@ -236,7 +234,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) } *x++ = L; b->wds = n = x - b->x; - n = 32*n - hi0bits(L); + n = ULbits*n - hi0bits(L); nbits = fpi->nbits; lostbits = 0; x = b->x; @@ -324,7 +322,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) break; case FPI_Round_near: if (lostbits & 2 - && (lostbits & 1) | x[0] & 1) + && (lostbits | x[0]) & 1) up = 1; break; case FPI_Round_up: @@ -345,8 +343,8 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) irv = STRTOG_Normal; } else if (b->wds > k - || (n = nbits & kmask) !=0 - && hi0bits(x[k-1]) < 32-n) { + || ((n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n)) { rshift(b,1); if (++e > fpi->emax) goto ovfl; diff --git a/lib/libc/gdtoa/hexnan.c b/lib/libc/gdtoa/hexnan.c index e07e069ad69..a443721f52d 100644 --- a/lib/libc/gdtoa/hexnan.c +++ b/lib/libc/gdtoa/hexnan.c @@ -77,7 +77,7 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0) if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') && *(CONST unsigned char*)(s+3) > ' ') s += 2; - while(c = *(CONST unsigned char*)++s) { + while((c = *(CONST unsigned char*)++s)) { if (!(h = hexdig[c])) { if (c <= ' ') { if (hd0 < havedig) { @@ -109,7 +109,7 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0) *sp = s + 1; break; } - } while(c = *++s); + } while((c = *++s)); #endif return STRTOG_NaN; } @@ -120,7 +120,7 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0) i = 1; *--x = 0; } - *x = (*x << 4) | h & 0xf; + *x = (*x << 4) | (h & 0xf); } if (!havedig) return STRTOG_NaN; diff --git a/lib/libc/gdtoa/misc.c b/lib/libc/gdtoa/misc.c index 8c5817764a1..6ad706b9142 100644 --- a/lib/libc/gdtoa/misc.c +++ b/lib/libc/gdtoa/misc.c @@ -55,6 +55,8 @@ 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]) !=0) { freelist[k] = rv->next; } @@ -94,14 +96,18 @@ Bfree #endif { if (v) { - if (v->k > Kmax) { - free(v); - return; - } - 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); + } } } @@ -113,8 +119,8 @@ lo0bits (ULong *y) #endif { - register int k; - register ULong x = *y; + int k; + ULong x = *y; if (x & 7) { if (x & 1) @@ -215,12 +221,12 @@ multadd int hi0bits_D2A #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; @@ -394,7 +400,7 @@ pow5mult b = multadd(b, p05[i-1], 0); if (b == NULL) return (NULL); - } + } if (!(k >>= 2)) return b; @@ -646,12 +652,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; @@ -664,16 +670,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; @@ -697,10 +703,10 @@ 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; #endif - return dval(d); + return dval(&d); } #undef d0 #undef d1 @@ -708,12 +714,13 @@ b2d Bigint * d2b #ifdef KR_headers - (d, e, bits) double d; int *e, *bits; + (dd, e, bits) double dd; int *e, *bits; #else - (double d, int *e, int *bits) + (double dd, int *e, int *bits) #endif { Bigint *b; + U d; #ifndef Sudden_Underflow int i; #endif @@ -721,11 +728,14 @@ d2b ULong *x, y, z; #ifdef VAX ULong d0, d1; - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; #else -#define d0 word0(d) -#define d1 word1(d) +#define d0 word0(&d) +#define d1 word1(&d) +#endif + d.d = dd; +#ifdef VAX + d0 = word0(&d) >> 16 | word0(&d) << 16; + d1 = word1(&d) >> 16 | word1(&d) << 16; #endif #ifdef Pack_32 @@ -751,7 +761,7 @@ d2b #ifdef Pack_32 if ( (y = d1) !=0) { if ( (k = lo0bits(&y)) !=0) { - x[0] = y | z << 32 - k; + x[0] = y | z << (32 - k); z >>= k; } else @@ -762,10 +772,6 @@ d2b b->wds = (x[1] = z) !=0 ? 2 : 1; } else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif k = lo0bits(&z); x[0] = z; #ifndef Sudden_Underflow @@ -824,7 +830,7 @@ d2b #endif #ifdef IBM *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); + *bits = 4*P + 8 - k - hi0bits(word0(&d) & Frac_mask); #else *e = de - Bias - (P-1) + k; *bits = P - k; @@ -877,7 +883,7 @@ strcp_D2A(a, b) char *a; char *b; strcp_D2A(char *a, CONST char *b) #endif { - while(*a = *b++) + while((*a = *b++)) a++; return a; } @@ -891,8 +897,8 @@ memcpy_D2A(a, b, len) Char *a; Char *b; size_t len; memcpy_D2A(void *a1, void *b1, size_t len) #endif { - register char *a = (char*)a1, *ae = a + len; - register char *b = (char*)b1, *a0 = a; + char *a = (char*)a1, *ae = a + len; + char *b = (char*)b1, *a0 = a; while(a < ae) *a++ = *b++; return a0; diff --git a/lib/libc/gdtoa/smisc.c b/lib/libc/gdtoa/smisc.c index 6cb9d4414fa..d063a38db27 100644 --- a/lib/libc/gdtoa/smisc.c +++ b/lib/libc/gdtoa/smisc.c @@ -34,9 +34,9 @@ THIS SOFTWARE. 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 dplen, nd0, nd; 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; @@ -66,16 +66,16 @@ s2b b = multadd(b, 10, *s++ - '0'); if (b == NULL) return (NULL); - } while(++i < nd0); - s++; + } while(++i < nd0); + s += dplen; } else - s += 10; + s += dplen + 9; for(; i < nd; i++) { b = multadd(b, 10, *s++ - '0'); if (b == NULL) return (NULL); - } + } return b; } @@ -87,33 +87,33 @@ 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); k = ka - kb + ULbits*(a->wds - b->wds); #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); } #ifdef INFNAN_CHECK diff --git a/lib/libc/gdtoa/strtod.c b/lib/libc/gdtoa/strtod.c index 2d2aa375105..ded47d86248 100644 --- a/lib/libc/gdtoa/strtod.c +++ b/lib/libc/gdtoa/strtod.c @@ -57,6 +57,28 @@ static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, #define Rounding Flt_Rounds #endif +#ifdef Avoid_Underflow /*{*/ + static double +sulp +#ifdef KR_headers + (x, scale) U *x; int scale; +#else + (U *x, int scale) +#endif +{ + U u; + double rv; + int i; + + rv = ulp(x); + if (!scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0) + return rv; /* Is there an example where i <= 0 ? */ + word0(&u) = Exp_1 + (i << Exp_shift); + word1(&u) = 0; + return rv * u.d; + } +#endif /*}*/ + double strtod #ifdef KR_headers @@ -71,31 +93,39 @@ strtod int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; - double aadj, aadj1, adj, rv, rv0; + double aadj; Long L; + U adj, aadj1, rv, rv0; ULong y, z; - Bigint *bb, *bb1, *bd, *bd0 = NULL, *bs, *delta; + Bigint *bb = NULL, *bb1, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL; +#ifdef Avoid_Underflow + ULong Lsb, Lsb1; +#endif #ifdef SET_INEXACT int inexact, oldinexact; #endif -#ifdef USE_LOCALE +#ifdef USE_LOCALE /*{{*/ #ifdef NO_LOCALE_CACHE char *decimalpoint = localeconv()->decimal_point; + int dplen = strlen(decimalpoint); #else char *decimalpoint; static char *decimalpoint_cache; + static int dplen; if (!(s0 = decimalpoint_cache)) { - size_t len; s0 = localeconv()->decimal_point; - len = strlen(s0) + 1; - if ((decimalpoint_cache = (char*)malloc(len))) { - strlcpy(decimalpoint_cache, s0, len); + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { + strlcpy(decimalpoint_cache, s0, strlen(s0) + 1); s0 = decimalpoint_cache; } + dplen = strlen(s0); } decimalpoint = (char*)s0; -#endif -#endif +#endif /*NO_LOCALE_CACHE*/ +#else /*USE_LOCALE}{*/ +#define dplen 1 +#endif /*USE_LOCALE}}*/ + #ifdef Honor_FLT_ROUNDS /*{*/ int Rounding; #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ @@ -111,7 +141,7 @@ strtod #endif /*}*/ sign = nz0 = nz = decpt = 0; - dval(rv) = 0.; + dval(&rv) = 0.; for(s = s00;;s++) switch(*s) { case '-': sign = 1; @@ -134,7 +164,7 @@ strtod } break2: if (*s == '0') { -#ifndef NO_HEX_FP /*{{*/ +#ifndef NO_HEX_FP /*{*/ { static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; Long exp; @@ -143,28 +173,20 @@ strtod case 'x': case 'X': { -#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) /*{{*/ +#ifdef Honor_FLT_ROUNDS FPI fpi1 = fpi; -#ifdef Honor_FLT_ROUNDS /*{{*/ fpi1.rounding = Rounding; -#else /*}{*/ - switch(fegetround()) { - case FE_TOWARDZERO: fpi1.rounding = 0; break; - case FE_UPWARD: fpi1.rounding = 2; break; - case FE_DOWNWARD: fpi1.rounding = 3; - } -#endif /*}}*/ -#else /*}{*/ +#else #define fpi1 fpi -#endif /*}}*/ +#endif switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { + case STRTOG_NoMemory: + goto ovfl; case STRTOG_NoNumber: s = s00; sign = 0; case STRTOG_Zero: break; - case STRTOG_NoMemory: - goto ovfl; default: if (bb) { copybits(bits, fpi.nbits, bb); @@ -175,7 +197,7 @@ strtod goto ret; } } -#endif +#endif /*}*/ nz0 = 1; while(*++s == '0') ; if (!*s) @@ -283,8 +305,8 @@ strtod --s; if (!match(&s,"inity")) ++s; - word0(rv) = 0x7ff00000; - word1(rv) = 0; + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; goto ret; } break; @@ -295,13 +317,13 @@ strtod if (*s == '(' /*)*/ && hexnan(&s, &fpinan, bits) == STRTOG_NaNbits) { - word0(rv) = 0x7ff00000 | bits[1]; - word1(rv) = bits[0]; + word0(&rv) = 0x7ff00000 | bits[1]; + word1(&rv) = bits[0]; } else { #endif - word0(rv) = NAN_WORD0; - word1(rv) = NAN_WORD1; + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; #ifndef No_Hex_NaN } #endif @@ -325,13 +347,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; } if (nd <= DBL_DIG #ifndef RND_PRODQUOT @@ -342,6 +364,7 @@ strtod ) { if (!e) goto ret; +#ifndef ROUND_BIASED_without_Round_Up if (e > 0) { if (e <= Ten_pmax) { #ifdef VAX @@ -350,11 +373,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 } @@ -366,25 +389,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; } @@ -394,14 +417,15 @@ 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 +#endif /* ROUND_BIASED_without_Round_Up */ } e1 += nd - k; @@ -429,67 +453,73 @@ strtod if (e1 > 0) { if ( (i = e1 & 15) !=0) - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; if (e1 &= ~15) { if (e1 > DBL_MAX_10_EXP) { ovfl: -#ifndef NO_ERRNO - errno = ERANGE; -#endif /* Can't trust HUGE_VAL */ #ifdef IEEE_Arith #ifdef Honor_FLT_ROUNDS 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; + range_err: + if (bd0) { + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + } +#ifndef NO_ERRNO + errno = ERANGE; +#endif 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) !=0) - dval(rv) /= tens[i]; + dval(&rv) /= tens[i]; if (e1 >>= 4) { if (e1 >= 1 << n_bigtens) goto undfl; @@ -498,44 +528,39 @@ strtod 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 (scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) >> Exp_shift)) > 0) { /* scaled rv is denormal; zap 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.; -#ifndef NO_ERRNO - errno = ERANGE; -#endif - if (bd0) - goto retfree; - goto ret; + dval(&rv) = 0.; + goto range_err; } #ifndef Avoid_Underflow - word0(rv) = Tiny0; - word1(rv) = Tiny1; + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; /* The refinement below will clean * this approximation up. */ @@ -548,7 +573,7 @@ strtod /* Put digits into bd: true value = bd * 10^e */ - bd0 = s2b(s0, nd0, nd, y); + bd0 = s2b(s0, nd0, nd, y, dplen); if (bd0 == NULL) goto ovfl; @@ -557,7 +582,7 @@ strtod if (bd == NULL) goto ovfl; Bcopy(bd, bd0); - bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bb = d2b(dval(&rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ if (bb == NULL) goto ovfl; bs = i2b(1); @@ -582,12 +607,19 @@ strtod bs2++; #endif #ifdef Avoid_Underflow + Lsb = LSB; + Lsb1 = 0; j = bbe - scale; i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; + j = P + 1 - bbbits; + if (i < Emin) { /* denormal */ + i = Emin - i; + j -= i; + if (i < 32) + Lsb <<= i; + else + Lsb1 = Lsb << (i-32); + } #else /*Avoid_Underflow*/ #ifdef Sudden_Underflow #ifdef IBM @@ -597,7 +629,7 @@ strtod #endif #else /*Sudden_Underflow*/ j = bbe; - i = j + bbbits - 1; /* logb(rv) */ + i = j + bbbits - 1; /* logb(&rv) */ if (i < Emin) /* denormal */ j += P - Emin; else @@ -631,22 +663,22 @@ strtod bb = lshift(bb, bb2); if (bb == NULL) goto ovfl; - } + } if (bd5 > 0) { bd = pow5mult(bd, bd5); if (bd == NULL) goto ovfl; - } + } if (bd2 > 0) { bd = lshift(bd, bd2); if (bd == NULL) goto ovfl; - } + } if (bs2 > 0) { bs = lshift(bs, bs2); if (bs == NULL) goto ovfl; - } + } delta = diff(bb, bd); if (delta == NULL) goto ovfl; @@ -666,15 +698,15 @@ strtod } if (Rounding) { if (dsign) { - adj = 1.; + dval(&adj) = 1.; goto apply_adj; } } else if (!dsign) { - adj = -1.; - if (!word1(rv) - && !(word0(rv) & Frac_mask)) { - y = word0(rv) & Exp_mask; + dval(&adj) = -1.; + if (!word1(&rv) + && !(word0(&rv) & Frac_mask)) { + y = word0(&rv) & Exp_mask; #ifdef Avoid_Underflow if (!scale || y > 2*P*Exp_msk1) #else @@ -685,66 +717,66 @@ strtod if (delta == NULL) goto ovfl; if (cmp(delta, bs) <= 0) - adj = -0.5; + dval(&adj) = -0.5; } } apply_adj: #ifdef Avoid_Underflow - if (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*ulp(dval(rv)); - word0(rv) -= P*Exp_msk1; + word0(&rv) += P*Exp_msk1; + dval(&rv) += adj*ulp(&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 = Rounding ? ceil(adj) : floor(adj); */ - y = adj; - if (y != adj) { + dval(&adj) = ratio(delta, bs); + if (adj.d < 1.) + dval(&adj) = 1.; + if (adj.d <= 0x7ffffffe) { + /* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */ + y = adj.d; + if (y != adj.d) { if (!((Rounding>>1) ^ dsign)) y++; - adj = y; + dval(&adj) = y; } } #ifdef Avoid_Underflow - if (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 *= ulp(dval(rv)); + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + word0(&rv) += P*Exp_msk1; + dval(&adj) *= ulp(&rv); if (dsign) - dval(rv) += adj; + dval(&rv) += adj; else - dval(rv) -= adj; - word0(rv) -= P*Exp_msk1; + dval(&rv) -= adj; + word0(&rv) -= P*Exp_msk1; goto cont; } #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - adj *= ulp(dval(rv)); + dval(&adj) *= ulp(&rv); if (dsign) { - if (word0(rv) == Big0 && word1(rv) == Big1) + 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*/ @@ -753,12 +785,12 @@ 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 (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 ) { @@ -785,32 +817,34 @@ strtod if (i == 0) { /* exactly half-way between */ if (dsign) { - if ((word0(rv) & Bndry_mask1) == Bndry_mask1 - && word1(rv) == ( + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 + && word1(&rv) == ( #ifdef Avoid_Underflow - (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) + if (word0(&rv) == Big0 && word1(&rv) == Big1) + goto ovfl; + 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; #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 @@ -825,7 +859,7 @@ strtod #else /*Sudden_Underflow}{*/ #ifdef Avoid_Underflow if (scale) { - L = word0(rv) & Exp_mask; + L = word0(&rv) & Exp_mask; if (L <= (2*P+1)*Exp_msk1) { if (L > (P+2)*Exp_msk1) /* round even ==> */ @@ -836,10 +870,10 @@ strtod } } #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 @@ -847,16 +881,33 @@ strtod #endif } #ifndef ROUND_BIASED - if (!(word1(rv) & LSB)) +#ifdef Avoid_Underflow + if (Lsb1) { + if (!(word0(&rv) & Lsb1)) + break; + } + else if (!(word1(&rv) & Lsb)) break; +#else + if (!(word1(&rv) & LSB)) + break; +#endif #endif if (dsign) - dval(rv) += ulp(dval(rv)); +#ifdef Avoid_Underflow + dval(&rv) += sulp(&rv, scale); +#else + dval(&rv) += ulp(&rv); +#endif #ifndef ROUND_BIASED else { - dval(rv) -= ulp(dval(rv)); +#ifdef Avoid_Underflow + dval(&rv) -= sulp(&rv, scale); +#else + dval(&rv) -= ulp(&rv); +#endif #ifndef Sudden_Underflow - if (!dval(rv)) + if (!dval(&rv)) goto undfl; #endif } @@ -868,14 +919,14 @@ strtod } if ((aadj = ratio(delta, bs)) <= 2.) { if (dsign) - aadj = aadj1 = 1.; - else if (word1(rv) || word0(rv) & Bndry_mask) { + aadj = dval(&aadj1) = 1.; + else if (word1(&rv) || word0(&rv) & Bndry_mask) { #ifndef Sudden_Underflow - if (word1(rv) == Tiny1 && !word0(rv)) + if (word1(&rv) == Tiny1 && !word0(&rv)) goto undfl; #endif aadj = 1.; - aadj1 = -1.; + dval(&aadj1) = -1.; } else { /* special case -- power of FLT_RADIX to be */ @@ -885,45 +936,45 @@ strtod aadj = 1./FLT_RADIX; else aadj *= 0.5; - aadj1 = -aadj; + dval(&aadj1) = -aadj; } } else { aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; + dval(&aadj1) = dsign ? aadj : -aadj; #ifdef Check_FLT_ROUNDS switch(Rounding) { case 2: /* towards +infinity */ - aadj1 -= 0.5; + dval(&aadj1) -= 0.5; break; case 0: /* towards 0 */ case 3: /* towards -infinity */ - aadj1 += 0.5; + dval(&aadj1) += 0.5; } #else if (Flt_Rounds == 0) - aadj1 += 0.5; + dval(&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; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += dval(&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 @@ -932,58 +983,58 @@ strtod if ((z = aadj) <= 0) z = 1; aadj = z; - aadj1 = dsign ? aadj : -aadj; + dval(&aadj1) = dsign ? aadj : -aadj; } - word0(aadj1) += (2*P+1)*Exp_msk1 - y; + word0(&aadj1) += (2*P+1)*Exp_msk1 - y; } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += dval(&adj); #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; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += dval(&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 (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 = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += dval(&adj); } #else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., + /* Compute dval(&adj) so that the IEEE rounding rules will + * correctly round rv + dval(&adj) in some half-way cases. + * If rv * ulp(&rv) is denormalized (i.e., * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid * trouble from bits lost to denormalization; * example: 1.2e-307 . */ if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); + dval(&aadj1) = (double)(int)(aadj + 0.5); if (!dsign) - aadj1 = -aadj1; + dval(&aadj1) = -dval(&aadj1); } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += adj; #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ } - z = word0(rv) & Exp_mask; + z = word0(&rv) & Exp_mask; #ifndef SET_INEXACT #ifdef Avoid_Underflow if (!scale) @@ -993,7 +1044,7 @@ strtod L = (Long)aadj; aadj -= L; /* The tolerances below are conservative. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) { if (aadj < .4999999 || aadj > .5000001) break; } @@ -1007,12 +1058,17 @@ strtod Bfree(bs); Bfree(delta); } + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); #ifdef SET_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) @@ -1020,36 +1076,30 @@ strtod #endif #ifdef Avoid_Underflow if (scale) { - word0(rv0) = Exp_1 - 2*P*Exp_msk1; - word1(rv0) = 0; - dval(rv) *= dval(rv0); + 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 (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); } diff --git a/lib/libc/gdtoa/strtodg.c b/lib/libc/gdtoa/strtodg.c index a4a422fd507..753f6bf0ec2 100644 --- a/lib/libc/gdtoa/strtodg.c +++ b/lib/libc/gdtoa/strtodg.c @@ -176,9 +176,9 @@ set_ones(Bigint *b, int n) rvOK #ifdef KR_headers (d, fpi, exp, bits, exact, rd, irv) - double d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; + U *d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; #else - (double d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) + (U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) #endif { Bigint *b; @@ -186,10 +186,10 @@ rvOK int bdif, e, j, k, k1, nb, rv; carry = rv = 0; - b = d2b(d, &e, &bdif); + b = d2b(dval(d), &e, &bdif); if (b == NULL) { *irv = STRTOG_NoMemory; - return 1; + return (1); } bdif -= nb = fpi->nbits; e += bdif; @@ -245,8 +245,8 @@ rvOK b = increment(b); if (b == NULL) { *irv = STRTOG_NoMemory; - return 1; - } + return (1); + } if ( (j = nb & kmask) !=0) j = ULbits - j; if (hi0bits(b->x[b->wds - 1]) != j) { @@ -261,9 +261,9 @@ rvOK b = lshift(b, -bdif); if (b == NULL) { *irv = STRTOG_NoMemory; - return 1; + return (1); + } } - } if (e < fpi->emin) { k = fpi->emin - e; e = fpi->emin; @@ -285,8 +285,8 @@ rvOK b = increment(b); if (b == NULL) { *irv = STRTOG_NoMemory; - return 1; - } + return (1); + } inex = STRTOG_Inexhi | STRTOG_Underflow; } else if (lostbits) @@ -312,9 +312,9 @@ rvOK static int #ifdef KR_headers -mantbits(d) double d; +mantbits(d) U *d; #else -mantbits(double d) +mantbits(U *d) #endif { ULong L; @@ -348,32 +348,36 @@ strtodg int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign; int sudden_underflow; CONST char *s, *s0, *s1; - double adj, adj0, rv, tol; + double adj0, tol; Long L; + U adj, rv; ULong *b, *be, y, z; Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; -#ifdef USE_LOCALE +#ifdef USE_LOCALE /*{{*/ #ifdef NO_LOCALE_CACHE char *decimalpoint = localeconv()->decimal_point; + int dplen = strlen(decimalpoint); #else char *decimalpoint; static char *decimalpoint_cache; + static int dplen; if (!(s0 = decimalpoint_cache)) { - size_t len; s0 = localeconv()->decimal_point; - len = strlen(s0) + 1; - if ((decimalpoint_cache = (char*)malloc(len))) { - strlcpy(decimalpoint_cache, s0, len); + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { + strlcpy(decimalpoint_cache, s0, strlen(s0) + 1); s0 = decimalpoint_cache; } + dplen = strlen(s0); } decimalpoint = (char*)s0; -#endif -#endif +#endif /*NO_LOCALE_CACHE*/ +#else /*USE_LOCALE}{*/ +#define dplen 1 +#endif /*USE_LOCALE}}*/ irv = STRTOG_Zero; denorm = sign = nz0 = nz = 0; - dval(rv) = 0.; + dval(&rv) = 0.; rvb = 0; nbits = fpi->nbits; for(s = s00;;s++) switch(*s) { @@ -567,30 +571,30 @@ strtodg if (!nd0) nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv) = y; + dval(&rv) = y; if (k > 9) - dval(rv) = tens[k - 9] * dval(rv) + z; + dval(&rv) = tens[k - 9] * dval(&rv) + z; bd0 = 0; if (nbits <= P && nd <= DBL_DIG) { if (!e) { - if (rvOK(dval(rv), fpi, exp, bits, 1, rd, &irv)) { + if (rvOK(&rv, fpi, exp, bits, 1, rd, &irv)) { if (irv == STRTOG_NoMemory) return (STRTOG_NoMemory); goto ret; - } + } } else if (e > 0) { if (e <= Ten_pmax) { #ifdef VAX goto vax_ovfl_check; #else - i = fivesbits[e] + mantbits(dval(rv)) <= P; - /* rv = */ rounded_product(dval(rv), tens[e]); - if (rvOK(dval(rv), fpi, exp, bits, i, rd, &irv)) { + i = fivesbits[e] + mantbits(&rv) <= P; + /* rv = */ rounded_product(dval(&rv), tens[e]); + if (rvOK(&rv, fpi, exp, bits, i, rd, &irv)) { if (irv == STRTOG_NoMemory) return (STRTOG_NoMemory); goto ret; - } + } e1 -= e; goto rv_notOK; #endif @@ -602,39 +606,39 @@ strtodg */ e2 = e - i; e1 -= 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: - dval(adj) = dval(rv); - word0(adj) -= P*Exp_msk1; - /* adj = */ rounded_product(dval(adj), tens[e2]); - if ((word0(adj) & Exp_mask) + dval(&adj) = dval(&rv); + word0(&adj) -= P*Exp_msk1; + /* adj = */ rounded_product(dval(&adj), tens[e2]); + if ((word0(&adj) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) goto rv_notOK; - word0(adj) += P*Exp_msk1; - dval(rv) = dval(adj); + word0(&adj) += P*Exp_msk1; + dval(&rv) = dval(&adj); #else - /* rv = */ rounded_product(dval(rv), tens[e2]); + /* rv = */ rounded_product(dval(&rv), tens[e2]); #endif - if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) { + if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) { if (irv == STRTOG_NoMemory) return (STRTOG_NoMemory); goto ret; - } + } e1 -= e2; } } #ifndef Inaccurate_Divide else if (e >= -Ten_pmax) { - /* rv = */ rounded_quotient(dval(rv), tens[-e]); - if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) { + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); + if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) { if (irv == STRTOG_NoMemory) return (STRTOG_NoMemory); goto ret; - } + } e1 -= e; } #endif @@ -647,45 +651,45 @@ strtodg e2 = 0; if (e1 > 0) { if ( (i = e1 & 15) !=0) - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; if (e1 &= ~15) { e1 >>= 4; - while(e1 >= (1 << n_bigtens-1)) { - e2 += ((word0(rv) & Exp_mask) + while(e1 >= (1 << (n_bigtens-1))) { + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; - dval(rv) *= bigtens[n_bigtens-1]; - e1 -= 1 << n_bigtens-1; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; + dval(&rv) *= bigtens[n_bigtens-1]; + e1 -= 1 << (n_bigtens-1); } - e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= bigtens[j]; + dval(&rv) *= bigtens[j]; } } else if (e1 < 0) { e1 = -e1; if ( (i = e1 & 15) !=0) - dval(rv) /= tens[i]; + dval(&rv) /= tens[i]; if (e1 &= ~15) { e1 >>= 4; - while(e1 >= (1 << n_bigtens-1)) { - e2 += ((word0(rv) & Exp_mask) + while(e1 >= (1 << (n_bigtens-1))) { + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; - dval(rv) *= tinytens[n_bigtens-1]; - e1 -= 1 << n_bigtens-1; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; + dval(&rv) *= tinytens[n_bigtens-1]; + e1 -= 1 << (n_bigtens-1); } - e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= tinytens[j]; + dval(&rv) *= tinytens[j]; } } #ifdef IBM @@ -696,7 +700,7 @@ strtodg */ e2 <<= 2; #endif - rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */ + rvb = d2b(dval(&rv), &rve, &rvbits); /* rv = rvb * 2^rve */ if (rvb == NULL) return (STRTOG_NoMemory); rve += e2; @@ -744,7 +748,7 @@ strtodg /* Put digits into bd: true value = bd * 10^e */ - bd0 = s2b(s0, nd0, nd, y); + bd0 = s2b(s0, nd0, nd, y, dplen); if (bd0 == NULL) return (STRTOG_NoMemory); @@ -805,24 +809,24 @@ strtodg bb = lshift(bb, bb2); if (bb == NULL) return (STRTOG_NoMemory); - } + } else if (bb2 < 0) rshift(bb, -bb2); if (bd5 > 0) { bd = pow5mult(bd, bd5); if (bd == NULL) return (STRTOG_NoMemory); - } + } if (bd2 > 0) { bd = lshift(bd, bd2); if (bd == NULL) return (STRTOG_NoMemory); - } + } if (bs2 > 0) { bs = lshift(bs, bs2); if (bs == NULL) return (STRTOG_NoMemory); - } + } asub = 1; inex = STRTOG_Inexhi; delta = diff(bb, bd); @@ -910,7 +914,7 @@ strtodg } else irv = STRTOG_Normal | STRTOG_Inexhi; - if (bbbits < nbits && !denorm || !(rvb->x[0] & 1)) + if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1)) break; if (dsign) { rvb = increment(rvb); @@ -929,7 +933,7 @@ strtodg } break; } - if ((dval(adj) = ratio(delta, bs)) <= 2.) { + if ((dval(&adj) = ratio(delta, bs)) <= 2.) { adj1: inex = STRTOG_Inexlo; if (dsign) { @@ -943,15 +947,15 @@ strtodg irv = STRTOG_Underflow | STRTOG_Inexlo; break; } - adj0 = dval(adj) = 1.; + adj0 = dval(&adj) = 1.; } else { - adj0 = dval(adj) *= 0.5; + adj0 = dval(&adj) *= 0.5; if (dsign) { asub = 0; inex = STRTOG_Inexlo; } - if (dval(adj) < 2147483647.) { + if (dval(&adj) < 2147483647.) { L = adj0; adj0 -= L; switch(rd) { @@ -970,12 +974,12 @@ strtodg inex = STRTOG_Inexact - inex; } } - dval(adj) = L; + dval(&adj) = L; } } y = rve + rvbits; - /* adj *= ulp(dval(rv)); */ + /* adj *= ulp(dval(&rv)); */ /* if (asub) rv -= adj; else rv += adj; */ if (!denorm && rvbits < nbits) { @@ -985,7 +989,7 @@ strtodg rve -= j; rvbits = nbits; } - ab = d2b(dval(adj), &abe, &abits); + ab = d2b(dval(&adj), &abe, &abits); if (ab == NULL) return (STRTOG_NoMemory); if (abe < 0) @@ -994,7 +998,7 @@ strtodg ab = lshift(ab, abe); if (ab == NULL) return (STRTOG_NoMemory); - } + } rvb0 = rvb; if (asub) { /* rv -= adj; */ @@ -1050,15 +1054,15 @@ strtodg z = rve + rvbits; if (y == z && L) { /* Can we stop now? */ - tol = dval(adj) * 5e-16; /* > max rel error */ - dval(adj) = adj0 - .5; - if (dval(adj) < -tol) { + tol = dval(&adj) * 5e-16; /* > max rel error */ + dval(&adj) = adj0 - .5; + if (dval(&adj) < -tol) { if (adj0 > tol) { irv |= inex; break; } } - else if (dval(adj) > tol && adj0 < 1. - tol) { + else if (dval(&adj) > tol && adj0 < 1. - tol) { irv |= inex; break; } @@ -1074,7 +1078,7 @@ strtodg rvb = lshift(rvb, j); if (rvb == NULL) return (STRTOG_NoMemory); - } + } else rshift(rvb, -j); rve -= j; diff --git a/lib/libc/gdtoa/strtof.c b/lib/libc/gdtoa/strtof.c index 691dbac4ee9..224491b50f3 100644 --- a/lib/libc/gdtoa/strtof.c +++ b/lib/libc/gdtoa/strtof.c @@ -58,7 +58,7 @@ strtof(CONST char *s, char **sp) case STRTOG_Normal: case STRTOG_NaNbits: - u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + u.L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23); break; case STRTOG_Denormal: @@ -67,7 +67,7 @@ strtof(CONST char *s, char **sp) case STRTOG_NoMemory: errno = ERANGE; - /* FALLTHROUGH */ + /* FALLTHROUGH */ case STRTOG_Infinite: u.L[0] = 0x7f800000; break; diff --git a/lib/libc/gdtoa/strtorx.c b/lib/libc/gdtoa/strtorx.c index 201d7149121..473642cfa0d 100644 --- a/lib/libc/gdtoa/strtorx.c +++ b/lib/libc/gdtoa/strtorx.c @@ -83,7 +83,8 @@ ULtox(UShort *L, ULong *bits, Long exp, int k) /* FALLTHROUGH */ case STRTOG_Infinite: L[_0] = 0x7fff; - L[_1] = L[_2] = L[_3] = L[_4] = 0; + L[_1] = 0x8000; + L[_2] = L[_3] = L[_4] = 0; break; case STRTOG_NaN: diff --git a/lib/libc/gdtoa/ulp.c b/lib/libc/gdtoa/ulp.c index 7810a5c8e64..17e9f862c44 100644 --- a/lib/libc/gdtoa/ulp.c +++ b/lib/libc/gdtoa/ulp.c @@ -34,13 +34,13 @@ THIS SOFTWARE. double ulp #ifdef KR_headers - (x) double x; + (x) U *x; #else - (double x) + (U *x) #endif { Long L; - double a; + U a; L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; #ifndef Sudden_Underflow @@ -49,22 +49,22 @@ ulp #ifdef IBM L |= Exp_msk1 >> 4; #endif - word0(a) = L; - word1(a) = 0; + word0(&a) = L; + word1(&a) = 0; #ifndef Sudden_Underflow } else { L = -L >> Exp_shift; if (L < Exp_shift) { - word0(a) = 0x80000 >> L; - word1(a) = 0; + word0(&a) = 0x80000 >> L; + word1(&a) = 0; } else { - word0(a) = 0; + word0(&a) = 0; L -= Exp_shift; - word1(a) = L >= 31 ? 1 : 1 << 31 - L; + word1(&a) = L >= 31 ? 1 : 1 << (31 - L); } } #endif - return a; + return dval(&a); } |