11,11 → 11,11 |
|
ANSI_SYNOPSIS |
#include <stdlib.h> |
double strtod(const char *<[str]>, char **<[tail]>); |
float strtof(const char *<[str]>, char **<[tail]>); |
double strtod(const char *restrict <[str]>, char **restrict <[tail]>); |
float strtof(const char *restrict <[str]>, char **restrict <[tail]>); |
|
double _strtod_r(void *<[reent]>, |
const char *<[str]>, char **<[tail]>); |
const char *restrict <[str]>, char **restrict <[tail]>); |
|
TRAD_SYNOPSIS |
#include <stdlib.h> |
128,11 → 128,17 |
#ifndef NO_IEEE_Scale |
#define Avoid_Underflow |
#undef tinytens |
/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ |
/* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */ |
/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ |
static _CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, |
9007199254740992.e-256 |
static _CONST double tinytens[] = { 1e-16, 1e-32, |
#ifdef _DOUBLE_IS_32BITS |
0.0, 0.0, 0.0 |
#else |
1e-64, 1e-128, |
9007199254740992. * 9007199254740992.e-256 |
#endif |
}; |
|
#endif |
#endif |
|
144,6 → 150,28 |
#define Rounding Flt_Rounds |
#endif |
|
#ifdef Avoid_Underflow /*{*/ |
static double |
_DEFUN (sulp, (x, scale), |
U x _AND |
int scale) |
{ |
U u; |
double rv; |
int i; |
|
rv = ulp(dval(x)); |
if (!scale || (i = 2*P + 1 - ((dword0(x) & Exp_mask) >> Exp_shift)) <= 0) |
return rv; /* Is there an example where i <= 0 ? */ |
dword0(u) = Exp_1 + (i << Exp_shift); |
#ifndef _DOUBLE_IS_32BITS |
dword1(u) = 0; |
#endif |
return rv * u.d; |
} |
#endif /*}*/ |
|
|
#ifndef NO_HEX_FP |
|
static void |
208,8 → 236,8 |
double |
_DEFUN (_strtod_r, (ptr, s00, se), |
struct _reent *ptr _AND |
_CONST char *s00 _AND |
char **se) |
_CONST char *__restrict s00 _AND |
char **__restrict se) |
{ |
#ifdef Avoid_Underflow |
int scale; |
221,7 → 249,10 |
U aadj1, rv, rv0; |
Long L; |
__ULong y, z; |
_Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; |
_Bigint *bb = NULL, *bb1, *bd = NULL, *bd0, *bs = NULL, *delta = NULL; |
#ifdef Avoid_Underflow |
__ULong Lsb, Lsb1; |
#endif |
#ifdef SET_INEXACT |
int inexact, oldinexact; |
#endif |
256,7 → 287,7 |
if (*s == '0') { |
#ifndef NO_HEX_FP |
{ |
static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; |
static _CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; |
Long exp; |
__ULong bits[2]; |
switch(s[1]) { |
279,6 → 310,8 |
switch((i = gethex(ptr, &s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { |
case STRTOG_NoNumber: |
s = s00; |
sign = 0; |
/* FALLTHROUGH */ |
case STRTOG_Zero: |
break; |
default: |
299,17 → 332,15 |
} |
s0 = s; |
y = z = 0; |
for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) { |
if (nd < DBL_DIG + 1) { |
for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) |
if (nd < 9) |
y = 10*y + c - '0'; |
else |
z = 10*z + c - '0'; |
} |
} |
nd0 = nd; |
if (strncmp (s, _localeconv_r (ptr)->decimal_point, |
strlen (_localeconv_r (ptr)->decimal_point)) == 0) { |
strlen (_localeconv_r (ptr)->decimal_point)) == 0) |
{ |
decpt = 1; |
c = *(s += strlen (_localeconv_r (ptr)->decimal_point)); |
if (!nd) { |
327,24 → 358,16 |
have_dig: |
nz++; |
if (c -= '0') { |
for(i = 1; i < nz; i++) { |
if (nd <= DBL_DIG + 1) { |
if (nd + i < 10) |
nf += nz; |
for(i = 1; i < nz; i++) |
if (nd++ < 9) |
y *= 10; |
else |
else if (nd <= DBL_DIG + 1) |
z *= 10; |
} |
} |
if (nd <= DBL_DIG + 1) { |
if (nd + i < 10) |
if (nd++ < 9) |
y = 10*y + c; |
else |
else if (nd <= DBL_DIG + 1) |
z = 10*z + c; |
} |
if (nd <= DBL_DIG + 1) { |
nf += nz; |
nd += nz; |
} |
nz = 0; |
} |
} |
392,7 → 415,7 |
#ifdef INFNAN_CHECK |
/* Check for Nan and Infinity */ |
__ULong bits[2]; |
static FPI fpinan = /* only 52 explicit bits */ |
static _CONST FPI fpinan = /* only 52 explicit bits */ |
{ 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; |
if (!decpt) |
switch(c) { |
693,12 → 716,20 |
/* Put digits into bd: true value = bd * 10^e */ |
|
bd0 = s2b(ptr, s0, nd0, nd, y); |
if (bd0 == NULL) |
goto ovfl; |
|
for(;;) { |
bd = Balloc(ptr,bd0->_k); |
if (bd == NULL) |
goto ovfl; |
Bcopy(bd, bd0); |
bb = d2b(ptr,dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ |
if (bb == NULL) |
goto ovfl; |
bs = i2b(ptr,1); |
if (bs == NULL) |
goto ovfl; |
|
if (e >= 0) { |
bb2 = bb5 = 0; |
718,12 → 749,19 |
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; |
j = P + 1 - bbbits; |
if (i < Emin) { /* denormal */ |
i = Emin - i; |
j -= i; |
if (i < 32) |
Lsb <<= i; |
else |
j = P + 1 - bbbits; |
Lsb1 = Lsb << (i-32); |
} |
#else /*Avoid_Underflow*/ |
#ifdef Sudden_Underflow |
#ifdef IBM |
755,19 → 793,37 |
} |
if (bb5 > 0) { |
bs = pow5mult(ptr, bs, bb5); |
if (bs == NULL) |
goto ovfl; |
bb1 = mult(ptr, bs, bb); |
if (bb1 == NULL) |
goto ovfl; |
Bfree(ptr, bb); |
bb = bb1; |
} |
if (bb2 > 0) |
if (bb2 > 0) { |
bb = lshift(ptr, bb, bb2); |
if (bd5 > 0) |
if (bb == NULL) |
goto ovfl; |
} |
if (bd5 > 0) { |
bd = pow5mult(ptr, bd, bd5); |
if (bd2 > 0) |
if (bd == NULL) |
goto ovfl; |
} |
if (bd2 > 0) { |
bd = lshift(ptr, bd, bd2); |
if (bs2 > 0) |
if (bd == NULL) |
goto ovfl; |
} |
if (bs2 > 0) { |
bs = lshift(ptr, bs, bs2); |
if (bs == NULL) |
goto ovfl; |
} |
delta = diff(ptr, bb, bd); |
if (delta == NULL) |
goto ovfl; |
dsign = delta->_sign; |
delta->_sign = 0; |
i = cmp(delta, bs); |
854,7 → 910,9 |
#endif /*Sudden_Underflow*/ |
#endif /*Avoid_Underflow*/ |
adj *= ulp(dval(rv)); |
if (dsign) |
if (dsign) { |
if (dword0(rv) == Big0 && dword1(rv) == Big1) |
goto ovfl; |
dval(rv) += adj; |
else |
dval(rv) -= adj; |
904,6 → 962,8 |
#endif |
0xffffffff)) { |
/*boundary case -- increment exponent*/ |
if (dword0(rv) == Big0 && dword1(rv) == Big1) |
goto ovfl; |
dword0(rv) = (dword0(rv) & Exp_mask) |
+ Exp_msk1 |
#ifdef IBM |
962,14 → 1022,31 |
#endif |
} |
#ifndef ROUND_BIASED |
#ifdef Avoid_Underflow |
if (Lsb1) { |
if (!(dword0(rv) & Lsb1)) |
break; |
} |
else if (!(dword1(rv) & Lsb)) |
break; |
#else |
if (!(dword1(rv) & LSB)) |
break; |
#endif |
#endif |
if (dsign) |
#ifdef Avoid_Underflow |
dval(rv) += sulp(rv, scale); |
#else |
dval(rv) += ulp(dval(rv)); |
#endif |
#ifndef ROUND_BIASED |
else { |
#ifdef Avoid_Underflow |
dval(rv) -= sulp(rv, scale); |
#else |
dval(rv) -= ulp(dval(rv)); |
#endif |
#ifndef Sudden_Underflow |
if (!dval(rv)) |
goto undfl; |
1046,7 → 1123,7 |
#ifdef Avoid_Underflow |
if (scale && y <= 2*P*Exp_msk1) { |
if (aadj <= 0x7fffffff) { |
if ((z = aadj) <= 0) |
if ((z = aadj) == 0) |
z = 1; |
aadj = z; |
dval(aadj1) = dsign ? aadj : -aadj; |
1178,7 → 1255,7 |
|
double |
_DEFUN (strtod, (s00, se), |
_CONST char *s00 _AND char **se) |
_CONST char *__restrict s00 _AND char **__restrict se) |
{ |
return _strtod_r (_REENT, s00, se); |
} |
1185,8 → 1262,8 |
|
float |
_DEFUN (strtof, (s00, se), |
_CONST char *s00 _AND |
char **se) |
_CONST char *__restrict s00 _AND |
char **__restrict se) |
{ |
double retval = _strtod_r (_REENT, s00, se); |
if (isnan (retval)) |