diff options
Diffstat (limited to 'winsup/mingw/mingwex/gdtoa/strtodg.c')
-rwxr-xr-x | winsup/mingw/mingwex/gdtoa/strtodg.c | 457 |
1 files changed, 212 insertions, 245 deletions
diff --git a/winsup/mingw/mingwex/gdtoa/strtodg.c b/winsup/mingw/mingwex/gdtoa/strtodg.c index 1f8de7c05..8de730f4b 100755 --- a/winsup/mingw/mingwex/gdtoa/strtodg.c +++ b/winsup/mingw/mingwex/gdtoa/strtodg.c @@ -35,21 +35,13 @@ THIS SOFTWARE. #include "locale.h" #endif - static CONST int +static const int fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, 24, 26, 28, 31, 33, 35, 38, 40, 42, 45, 47, 49, 52 -#ifdef VAX - , 54, 56 -#endif - }; +}; - Bigint * -#ifdef KR_headers -increment(b) Bigint *b; -#else -increment(Bigint *b) -#endif +Bigint *increment (Bigint *b) { ULong *x, *xe; Bigint *b1; @@ -64,9 +56,9 @@ increment(Bigint *b) if (*x < (ULong)0xffffffffL) { ++*x; return b; - } + } *x++ = 0; - } while(x < xe); + } while(x < xe); #else do { y = *x + carry; @@ -74,7 +66,7 @@ increment(Bigint *b) *x++ = y & 0xffff; if (!carry) return b; - } while(x < xe); + } while(x < xe); if (carry) #endif { @@ -83,18 +75,13 @@ increment(Bigint *b) Bcopy(b1,b); Bfree(b); b = b1; - } - b->x[b->wds++] = 1; } - return b; + b->x[b->wds++] = 1; } + return b; +} - int -#ifdef KR_headers -decrement(b) Bigint *b; -#else -decrement(Bigint *b) -#endif +void decrement (Bigint *b) { ULong *x, *xe; #ifdef Pack_16 @@ -108,26 +95,19 @@ decrement(Bigint *b) if (*x) { --*x; break; - } - *x++ = 0xffffffffL; } - while(x < xe); + *x++ = 0xffffffffL; + } while(x < xe); #else do { y = *x - borrow; borrow = (y & 0x10000) >> 16; *x++ = y & 0xffff; - } while(borrow && x < xe); + } while(borrow && x < xe); #endif - return STRTOG_Inexlo; - } +} - static int -#ifdef KR_headers -all_on(b, n) Bigint *b; int n; -#else -all_on(Bigint *b, int n) -#endif +static int all_on (Bigint *b, int n) { ULong *x, *xe; @@ -139,14 +119,9 @@ all_on(Bigint *b, int n) if (n &= kmask) return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON; return 1; - } +} - Bigint * -#ifdef KR_headers -set_ones(b, n) Bigint *b; int n; -#else -set_ones(Bigint *b, int n) -#endif +Bigint *set_ones (Bigint *b, int n) { int k; ULong *x, *xe; @@ -155,7 +130,7 @@ set_ones(Bigint *b, int n) if (b->k < k) { Bfree(b); b = Balloc(k); - } + } k = n >> kshift; if (n &= kmask) k++; @@ -167,30 +142,24 @@ set_ones(Bigint *b, int n) if (n) x[-1] >>= ULbits - n; return b; - } +} - static int -rvOK -#ifdef KR_headers - (d, fpi, exp, bits, exact, rd, irv) - double 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) -#endif +static int rvOK (dbl_union *d, FPI *fpi, Long *exp, ULong *bits, + int exact, int rd, int *irv) { Bigint *b; ULong carry, inex, lostbits; int bdif, e, j, k, k1, nb, rv; carry = rv = 0; - b = d2b(d, &e, &bdif); + b = d2b(dval(d), &e, &bdif); bdif -= nb = fpi->nbits; e += bdif; if (bdif <= 0) { if (exact) goto trunc; goto ret; - } + } if (P == nb) { if ( #ifndef IMPRECISE_INEXACT @@ -204,11 +173,11 @@ rvOK #endif ) goto trunc; goto ret; - } + } switch(rd) { - case 1: + case 1: /* round down (toward -Infinity) */ goto trunc; - case 2: + case 2: /* round up (toward +Infinity) */ break; default: /* round near */ k = bdif - 1; @@ -220,11 +189,11 @@ rvOK if (b->x[0] & 2) break; goto trunc; - } + } if (b->x[k>>kshift] & ((ULong)1 << (k & kmask))) break; goto trunc; - } + } /* "break" cases: round up 1 bit, then truncate; bdif > 0 */ carry = 1; trunc: @@ -243,9 +212,9 @@ rvOK lostbits = b->x[0] & 1; rshift(b, 1); e++; - } } } + } else if (bdif < 0) b = lshift(b, -bdif); if (e < fpi->emin) { @@ -254,7 +223,7 @@ rvOK if (k > nb || fpi->sudden_underflow) { b->wds = inex = 0; *irv = STRTOG_Underflow | STRTOG_Inexlo; - } + } else { k1 = k - 1; if (k1 > 0 && !lostbits) @@ -268,19 +237,17 @@ rvOK if (carry) { b = increment(b); inex = STRTOG_Inexhi | STRTOG_Underflow; - } + } else if (lostbits) inex = STRTOG_Inexlo | STRTOG_Underflow; - } } + } else if (e > fpi->emax) { e = fpi->emax + 1; *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; -#ifndef NO_ERRNO - errno = ERANGE; -#endif + SET_ERRNO(ERANGE); b->wds = inex = 0; - } + } *exp = e; copybits(bits, nb, b); *irv |= inex; @@ -288,54 +255,55 @@ rvOK ret: Bfree(b); return rv; - } +} - static int -#ifdef KR_headers -mantbits(d) double d; -#else -mantbits(double d) -#endif +static int mantbits (dbl_union *d) { ULong L; -#ifdef VAX - L = word1(d) << 16 | word1(d) >> 16; - if (L) -#else if ( (L = word1(d)) !=0) -#endif return P - lo0bits(&L); -#ifdef VAX - L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11; -#else L = word0(d) | Exp_msk1; -#endif return P - 32 - lo0bits(&L); - } +} - int -__strtodg -#ifdef KR_headers - (s00, se, fpi, exp, bits) - CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits; -#else - (CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits) -#endif +int __strtodg (const char *s00, char **se, FPI *fpi, Long *exp, ULong *bits) { int abe, abits, asub; int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm; int dsign, e, e1, e2, emin, esign, finished, i, inex, irv; 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; + const char *s, *s0, *s1; + double adj0, tol; Long L; - ULong y, z; + union _dbl_union adj, rv; + ULong *b, *be, y, z; Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; +#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)) { + s0 = localeconv()->decimal_point; + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { + strcpy(decimalpoint_cache, s0); + s0 = decimalpoint_cache; + } + dplen = strlen(s0); + } + decimalpoint = (char*)s0; +#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) { @@ -360,7 +328,7 @@ __strtodg continue; default: goto break2; - } + } break2: if (*s == '0') { #ifndef NO_HEX_FP @@ -371,15 +339,15 @@ __strtodg if (irv == STRTOG_NoNumber) { s = s00; sign = 0; - } + } goto ret; - } + } #endif nz0 = 1; while(*++s == '0') ; if (!*s) goto ret; - } + } sudden_underflow = fpi->sudden_underflow; s0 = s; y = z = 0; @@ -390,13 +358,17 @@ __strtodg z = 10*z + c - '0'; nd0 = nd; #ifdef USE_LOCALE - if (c == *localeconv()->decimal_point) + if (c == *decimalpoint) { + for(i = 1; decimalpoint[i]; ++i) + if (s[i] != decimalpoint[i]) + goto dig_done; + s += i; + c = *s; #else - if (c == '.') + if (c == '.') { + c = *++s; #endif - { decpt = 1; - c = *++s; if (!nd) { for(; c == '0'; c = *++s) nz++; @@ -405,9 +377,9 @@ __strtodg nf += nz; nz = 0; goto have_dig; - } - goto dig_done; } + goto dig_done; + } for(; c >= '0' && c <= '9'; c = *++s) { have_dig: nz++; @@ -423,9 +395,9 @@ __strtodg else if (nd <= DBL_DIG + 1) z = 10*z + c; nz = 0; - } } } + }/*}*/ dig_done: e = 0; if (c == 'e' || c == 'E') { @@ -433,7 +405,7 @@ __strtodg irv = STRTOG_NoNumber; s = s00; goto ret; - } + } s00 = s; esign = 0; switch(c = *++s) { @@ -441,7 +413,7 @@ __strtodg esign = 1; case '+': c = *++s; - } + } if (c >= '0' && c <= '9') { while(c == '0') c = *++s; @@ -459,13 +431,13 @@ __strtodg e = (int)L; if (esign) e = -e; - } + } else e = 0; - } + } else s = s00; - } + } if (!nd) { if (!nz && !nz0) { #ifdef INFNAN_CHECK @@ -480,7 +452,7 @@ __strtodg ++s; irv = STRTOG_Infinite; goto infnanexp; - } + } break; case 'n': case 'N': @@ -492,14 +464,14 @@ __strtodg irv = hexnan(&s, fpi, bits); #endif goto infnanexp; - } - } + } + } #endif /* INFNAN_CHECK */ irv = STRTOG_NoNumber; s = s00; - } - goto ret; } + goto ret; + } irv = STRTOG_Normal; e1 = e -= nf; @@ -513,7 +485,7 @@ __strtodg break; case FPI_Round_down: rd = 1 + sign; - } + } /* Now we have nd0 digits, starting at s0, followed by a * decimal point, followed by nd-nd0 digits. The number we're @@ -523,28 +495,24 @@ __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)) 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)) goto ret; e1 -= e; goto rv_notOK; -#endif - } + } i = DBL_DIG - nd; if (e <= Ten_pmax + i) { /* A fancier test would sometimes let us do @@ -552,37 +520,22 @@ __strtodg */ e2 = e - i; e1 -= 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) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto rv_notOK; - word0(adj) += P*Exp_msk1; - dval(rv) = dval(adj); -#else - /* rv = */ rounded_product(dval(rv), tens[e2]); -#endif - if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + dval(&rv) *= tens[i]; + /* rv = */ rounded_product(dval(&rv), tens[e2]); + if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) 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)) goto ret; e1 -= e; - } -#endif } +#endif + } rv_notOK: e1 += nd - k; @@ -591,62 +544,54 @@ __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) + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; - dval(rv) *= bigtens[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) + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; - dval(rv) *= tinytens[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 - /* e2 is a correction to the (base 2) exponent of the return - * value, reflecting adjustments above to avoid overflow in the - * native arithmetic. For native IBM (base 16) arithmetic, we - * must multiply e2 by 4 to change from base 16 to 2. - */ - e2 <<= 2; -#endif - rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */ + } + rvb = d2b(dval(&rv), &rve, &rvbits); /* rv = rvb * 2^rve */ rve += e2; if ((j = rvbits - nbits) > 0) { rshift(rvb, j); rvbits = nbits; rve += j; - } + } bb0 = 0; /* trailing zero bits in rvb */ e2 = rve + rvbits - nbits; if (e2 > fpi->emax + 1) @@ -658,7 +603,7 @@ __strtodg if (j > 0) { rvb = lshift(rvb, j); rvbits += j; - } + } else if (j < 0) { rvbits += j; if (rvbits <= 0) { @@ -669,22 +614,22 @@ __strtodg *exp = emin; irv = STRTOG_Underflow | STRTOG_Inexlo; goto ret; - } - rvb->x[0] = rvb->wds = rvbits = 1; } + rvb->x[0] = rvb->wds = rvbits = 1; + } else rshift(rvb, -j); - } + } rve = rve1 = emin; if (sudden_underflow && e2 + 1 < emin) goto ufl; - } + } /* Now the hard part -- adjusting rv to the correct value.*/ /* Put digits into bd: true value = bd * 10^e */ - bd0 = s2b(s0, nd0, nd, y); + bd0 = s2b(s0, nd0, nd, y, dplen); for(;;) { bd = Balloc(bd0->k); @@ -698,11 +643,11 @@ __strtodg if (e >= 0) { bb2 = bb5 = 0; bd2 = bd5 = e; - } + } else { bb2 = bb5 = -e; bd2 = bd5 = 0; - } + } if (bbe >= 0) bb2 += bbe; else @@ -721,13 +666,13 @@ __strtodg bb2 -= i; bd2 -= i; bs2 -= i; - } + } if (bb5 > 0) { bs = pow5mult(bs, bb5); bb1 = mult(bs, bb); Bfree(bb); bb = bb1; - } + } bb2 -= bb0; if (bb2 > 0) bb = lshift(bb, bb2); @@ -754,7 +699,7 @@ __strtodg if (dsign != 0) { irv |= STRTOG_Inexhi; goto adj1; - } + } irv |= STRTOG_Inexlo; if (rve1 == emin) goto adj1; @@ -762,16 +707,16 @@ __strtodg i++, j -= ULbits) { if (rvb->x[i] & ALL_ON) goto adj1; - } + } if (j > 1 && lo0bits(rvb->x + i) < j - 1) goto adj1; rve = rve1 - 1; rvb = set_ones(rvb, rvbits = nbits); break; - } + } irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi; break; - } + } if (i < 0) { /* Error is less than half an ulp -- check for * special case of mantissa a power of two. @@ -785,9 +730,9 @@ __strtodg if (cmp(delta, bs) > 0) { irv = STRTOG_Normal | STRTOG_Inexlo; goto drop_down; - } - break; } + break; + } if (i == 0) { /* exactly half-way between */ if (dsign) { @@ -799,9 +744,9 @@ __strtodg irv = STRTOG_Normal | STRTOG_Inexhi; denorm = 0; break; - } - irv = STRTOG_Normal | STRTOG_Inexlo; } + irv = STRTOG_Normal | STRTOG_Inexlo; + } else if (bbbits == 1) { irv = STRTOG_Normal; drop_down: @@ -811,55 +756,53 @@ __strtodg if (rvb->wds == 1 && rvb->x[0] == 1) sudden_underflow = 1; break; - } + } rve -= nbits; rvb = set_ones(rvb, rvbits = nbits); break; - } + } else irv = STRTOG_Normal | STRTOG_Inexhi; if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1)) break; if (dsign) { rvb = increment(rvb); - if ( (j = rvbits & kmask) !=0) - j = ULbits - j; - if (hi0bits(rvb->x[(rvb->wds - 1) >> kshift]) - != j) + j = kmask & (ULbits - (rvbits & kmask)); + if (hi0bits(rvb->x[rvb->wds - 1]) != j) rvbits++; irv = STRTOG_Normal | STRTOG_Inexhi; - } + } else { if (bbbits == 1) goto undfl; decrement(rvb); irv = STRTOG_Normal | STRTOG_Inexlo; - } - break; } - if ((dval(adj) = ratio(delta, bs)) <= 2.) { + break; + } + if ((dval(&adj) = ratio(delta, bs)) <= 2.) { adj1: inex = STRTOG_Inexlo; if (dsign) { asub = 0; inex = STRTOG_Inexhi; - } + } else if (denorm && bbbits <= 1) { undfl: rvb->wds = 0; rve = emin; 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) { @@ -876,22 +819,22 @@ __strtodg inc_L: L++; inex = STRTOG_Inexact - inex; - } - } - dval(adj) = L; + } } + dval(&adj) = L; } + } y = rve + rvbits; - /* adj *= ulp(dval(rv)); */ + /* adj *= ulp(&rv); */ /* if (asub) rv -= adj; else rv += adj; */ if (!denorm && rvbits < nbits) { rvb = lshift(rvb, j = nbits - rvbits); rve -= j; rvbits = nbits; - } - ab = d2b(dval(adj), &abe, &abits); + } + ab = d2b(dval(&adj), &abe, &abits); if (abe < 0) rshift(ab, -abe); else if (abe > 0) @@ -911,15 +854,15 @@ __strtodg if (rve1 == emin) { --rvbits; denorm = 1; - } + } else { rvb = lshift(rvb, 1); --rve; --rve1; L = finished = 0; - } } } + } else { rvb = sum(rvb, ab); k = rvb->wds - 1; @@ -928,15 +871,15 @@ __strtodg if (denorm) { if (++rvbits == nbits) denorm = 0; - } + } else { rshift(rvb, 1); rve++; rve1++; L = 0; - } } } + } Bfree(ab); Bfree(rvb0); if (finished) @@ -945,32 +888,32 @@ __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; - } } + } bb0 = denorm ? 0 : trailz(rvb); Bfree(bb); Bfree(bd); Bfree(bs); Bfree(delta); - } + } if (!denorm && (j = nbits - rvbits)) { if (j > 0) rvb = lshift(rvb, j); else rshift(rvb, -j); rve -= j; - } + } *exp = rve; Bfree(bb); Bfree(bd); @@ -978,28 +921,52 @@ __strtodg Bfree(bd0); Bfree(delta); if (rve > fpi->emax) { + switch(fpi->rounding & 3) { + case FPI_Round_near: + goto huge; + case FPI_Round_up: + if (!sign) + goto huge; + break; + case FPI_Round_down: + if (sign) + goto huge; + } + /* Round to largest representable magnitude */ + Bfree(rvb); + rvb = 0; + irv = STRTOG_Normal | STRTOG_Inexlo; + *exp = fpi->emax; + b = bits; + be = b + ((fpi->nbits + 31) >> 5); + while(b < be) + *b++ = -1; + if ((j = fpi->nbits & 0x1f)) + *--be >>= (32 - j); + goto ret; huge: rvb->wds = 0; irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; -#ifndef NO_ERRNO - errno = ERANGE; -#endif + SET_ERRNO(ERANGE); infnanexp: *exp = fpi->emax + 1; - } + } ret: if (denorm) { if (sudden_underflow) { rvb->wds = 0; irv = STRTOG_Underflow | STRTOG_Inexlo; - } + SET_ERRNO(ERANGE); + } else { irv = (irv & ~STRTOG_Retmask) | (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero); - if (irv & STRTOG_Inexact) + if (irv & STRTOG_Inexact) { irv |= STRTOG_Underflow; + SET_ERRNO(ERANGE); } } + } if (se) *se = (char *)s; if (sign) @@ -1007,6 +974,6 @@ __strtodg if (rvb) { copybits(bits, nbits, rvb); Bfree(rvb); - } - return irv; } + return irv; +} |