summaryrefslogtreecommitdiffstats
path: root/winsup/mingw/mingwex/gdtoa/strtodg.c
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/mingw/mingwex/gdtoa/strtodg.c')
-rwxr-xr-xwinsup/mingw/mingwex/gdtoa/strtodg.c457
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;
+}