Browse Source

Make code ANSI/ISO C conformant. Formerly undefined constructs were used

making load/store architectures (like mips&alpha) fail whn compiled with
gcc -O2.
OPENBSD_2_4
niklas 26 years ago
parent
commit
09df05bd48
1 changed files with 119 additions and 103 deletions
  1. +119
    -103
      src/lib/libc/stdlib/strtod.c

+ 119
- 103
src/lib/libc/stdlib/strtod.c View File

@ -90,7 +90,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: strtod.c,v 1.10 1998/08/11 22:04:29 niklas Exp $";
static char *rcsid = "$OpenBSD: strtod.c,v 1.11 1998/08/12 22:16:38 niklas Exp $";
#endif /* LIBC_SCCS and not lint */
#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
@ -222,12 +222,17 @@ Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
IBM should be defined.
#endif
typedef union {
double d;
ULong ul[2];
} _double;
#define value(x) ((x).d)
#ifdef IEEE_LITTLE_ENDIAN
#define word0(x) ((ULong *)&x)[1]
#define word1(x) ((ULong *)&x)[0]
#define word0(x) ((x).ul[1])
#define word1(x) ((x).ul[0])
#else
#define word0(x) ((ULong *)&x)[0]
#define word1(x) ((ULong *)&x)[1]
#define word0(x) ((x).ul[0])
#define word1(x) ((x).ul[1])
#endif
/* The following definition of Storeinc is appropriate for MIPS processors.
@ -909,14 +914,16 @@ diff
static double
ulp
#ifdef KR_headers
(x) double x;
(_x) double _x;
#else
(double x)
(double _x)
#endif
{
_double x;
register Long L;
double a;
_double a;
value(x) = _x;
L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
#ifndef Sudden_Underflow
if (L > 0) {
@ -941,7 +948,7 @@ ulp
}
}
#endif
return a;
return value(a);
}
static double
@ -954,7 +961,7 @@ b2d
{
ULong *xa, *xa0, w, y, z;
int k;
double d;
_double d;
#ifdef VAX
ULong d0, d1;
#else
@ -1011,22 +1018,27 @@ b2d
#undef d0
#undef d1
#endif
return d;
return value(d);
}
static Bigint *
d2b
#ifdef KR_headers
(d, e, bits) double d; int *e, *bits;
(_d, e, bits) double d; int *e, *bits;
#else
(double d, int *e, int *bits)
(double _d, int *e, int *bits)
#endif
{
Bigint *b;
int de, i, k;
ULong *x, y, z;
_double d;
#ifdef VAX
ULong d0, d1;
#endif
value(d) = _d;
#ifdef VAX
d0 = word0(d) >> 16 | word0(d) << 16;
d1 = word1(d) >> 16 | word1(d) << 16;
#else
@ -1151,11 +1163,11 @@ ratio
(Bigint *a, Bigint *b)
#endif
{
double da, db;
_double da, db;
int k, ka, kb;
da = b2d(a, &ka);
db = b2d(b, &kb);
value(da) = b2d(a, &ka);
value(db) = b2d(b, &kb);
#ifdef Pack_32
k = ka - kb + 32*(a->wds - b->wds);
#else
@ -1181,7 +1193,7 @@ ratio
word0(db) += k*Exp_msk1;
}
#endif
return da / db;
return value(da) / value(db);
}
static CONST double
@ -1221,7 +1233,8 @@ strtod
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, 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, aadj1, adj;
_double rv, rv0;
Long L;
ULong y, z;
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
@ -1233,7 +1246,7 @@ strtod
#endif
sign = nz0 = nz = 0;
rv = 0.;
value(rv) = 0.;
for(s = s00; isspace((unsigned char) *s); s++)
@ -1350,9 +1363,9 @@ strtod
if (!nd0)
nd0 = nd;
k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
rv = y;
value(rv) = y;
if (k > 9)
rv = tens[k - 9] * rv + z;
value(rv) = tens[k - 9] * value(rv) + z;
bd0 = 0;
if (nd <= DBL_DIG
#ifndef RND_PRODQUOT
@ -1366,7 +1379,8 @@ strtod
#ifdef VAX
goto vax_ovfl_check;
#else
/* rv = */ rounded_product(rv, tens[e]);
/* value(rv) = */ rounded_product(value(rv),
tens[e]);
goto ret;
#endif
}
@ -1376,27 +1390,30 @@ strtod
* this for larger i values.
*/
e -= i;
rv *= tens[i];
value(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(rv, tens[e]);
/* value(rv) = */ rounded_product(value(rv),
tens[e]);
if ((word0(rv) & Exp_mask)
> Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
goto ovfl;
word0(rv) += P*Exp_msk1;
#else
/* rv = */ rounded_product(rv, tens[e]);
/* value(rv) = */ rounded_product(value(rv),
tens[e]);
#endif
goto ret;
}
}
#ifndef Inaccurate_Divide
else if (e >= -Ten_pmax) {
/* rv = */ rounded_quotient(rv, tens[-e]);
/* value(rv) = */ rounded_quotient(value(rv),
tens[-e]);
goto ret;
}
#endif
@ -1407,13 +1424,13 @@ strtod
if (e1 > 0) {
if (i = e1 & 15)
rv *= tens[i];
value(rv) *= tens[i];
if (e1 &= ~15) {
if (e1 > DBL_MAX_10_EXP) {
ovfl:
errno = ERANGE;
#ifdef __STDC__
rv = HUGE_VAL;
value(rv) = HUGE_VAL;
#else
/* Can't trust HUGE_VAL */
#ifdef IEEE_Arith
@ -1431,10 +1448,10 @@ strtod
if (e1 >>= 4) {
for(j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
rv *= bigtens[j];
value(rv) *= bigtens[j];
/* The last multiplication could overflow. */
word0(rv) -= P*Exp_msk1;
rv *= bigtens[j];
value(rv) *= bigtens[j];
if ((z = word0(rv) & Exp_mask)
> Exp_msk1*(DBL_MAX_EXP+Bias-P))
goto ovfl;
@ -1453,23 +1470,23 @@ strtod
else if (e1 < 0) {
e1 = -e1;
if (i = e1 & 15)
rv /= tens[i];
value(rv) /= tens[i];
if (e1 &= ~15) {
e1 >>= 4;
if (e1 >= 1 << n_bigtens)
goto undfl;
for(j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
rv *= tinytens[j];
value(rv) *= tinytens[j];
/* The last multiplication could underflow. */
rv0 = rv;
rv *= tinytens[j];
if (!rv) {
rv = 2.*rv0;
rv *= tinytens[j];
if (!rv) {
value(rv0) = value(rv);
value(rv) *= tinytens[j];
if (!value(rv)) {
value(rv) = 2.*value(rv0);
value(rv) *= tinytens[j];
if (!value(rv)) {
undfl:
rv = 0.;
value(rv) = 0.;
errno = ERANGE;
if (bd0)
goto retfree;
@ -1493,7 +1510,7 @@ strtod
for(;;) {
bd = Balloc(bd0->k);
Bcopy(bd, bd0);
bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
bs = i2b(1);
if (e >= 0) {
@ -1605,12 +1622,12 @@ strtod
break;
#endif
if (dsign)
rv += ulp(rv);
value(rv) += ulp(value(rv));
#ifndef ROUND_BIASED
else {
rv -= ulp(rv);
value(rv) -= ulp(value(rv));
#ifndef Sudden_Underflow
if (!rv)
if (!value(rv))
goto undfl;
#endif
}
@ -1661,10 +1678,10 @@ strtod
/* Check for overflow */
if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
rv0 = rv;
value(rv0) = value(rv);
word0(rv) -= P*Exp_msk1;
adj = aadj1 * ulp(rv);
rv += adj;
adj = aadj1 * ulp(value(rv));
value(rv) += adj;
if ((word0(rv) & Exp_mask) >=
Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
if (word0(rv0) == Big0 && word1(rv0) == Big1)
@ -1679,10 +1696,10 @@ strtod
else {
#ifdef Sudden_Underflow
if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
rv0 = rv;
value(rv0) = value(rv);
word0(rv) += P*Exp_msk1;
adj = aadj1 * ulp(rv);
rv += adj;
adj = aadj1 * ulp(value(rv));
value(rv) += adj;
#ifdef IBM
if ((word0(rv) & Exp_mask) < P*Exp_msk1)
#else
@ -1700,8 +1717,8 @@ strtod
word0(rv) -= P*Exp_msk1;
}
else {
adj = aadj1 * ulp(rv);
rv += adj;
adj = aadj1 * ulp(value(rv));
value(rv) += adj;
}
#else
/* Compute adj so that the IEEE rounding rules will
@ -1716,8 +1733,8 @@ strtod
if (!dsign)
aadj1 = -aadj1;
}
adj = aadj1 * ulp(rv);
rv += adj;
adj = aadj1 * ulp(value(rv));
value(rv) += adj;
#endif
}
z = word0(rv) & Exp_mask;
@ -1748,7 +1765,7 @@ strtod
ret:
if (se)
*se = (char *)s;
return sign ? -rv : rv;
return sign ? -value(rv) : value(rv);
}
static int
@ -1894,10 +1911,10 @@ quorem
char *
__dtoa
#ifdef KR_headers
(d, mode, ndigits, decpt, sign, rve)
double d; int mode, ndigits, *decpt, *sign; char **rve;
(_d, mode, ndigits, decpt, sign, rve)
double _d; int mode, ndigits, *decpt, *sign; char **rve;
#else
(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
#endif
{
/* Arguments ndigits, decpt, sign are similar to those
@ -1943,11 +1960,13 @@ __dtoa
ULong x;
#endif
Bigint *b, *b1, *delta, *mlo, *mhi, *S;
double d2, ds, eps;
double ds;
char *s, *s0;
static Bigint *result;
static int result_k;
_double d, d2, eps;
value(d) = _d;
if (result) {
result->k = result_k;
result->maxwds = 1 << result_k;
@ -1987,9 +2006,9 @@ __dtoa
}
#endif
#ifdef IBM
d += 0; /* normalize */
value(d) += 0; /* normalize */
#endif
if (!d) {
if (!value(d)) {
*decpt = 1;
s = "0";
if (rve)
@ -1997,22 +2016,18 @@ __dtoa
return s;
}
b = d2b(d, &be, &bbits);
b = d2b(value(d), &be, &bbits);
#ifdef Sudden_Underflow
i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
#else
if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
#endif
d2 = d;
#ifdef __GNUC__
/* Do not move instructions depending on d2 over this line. */
__asm__ __volatile__ ("" : : "X" (d2) : "memory");
#endif
value(d2) = value(d);
word0(d2) &= Frac_mask1;
word0(d2) |= Exp_11;
#ifdef IBM
if (j = 11 - hi0bits(word0(d2) & Frac_mask))
d2 /= 1 << j;
value(d2) /= 1 << j;
#endif
/* log(x) ~=~ log(1.5) + (x-1.5)/1.5
@ -2051,19 +2066,20 @@ __dtoa
i = bbits + be + (Bias + (P-1) - 1);
x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
: word1(d) << 32 - i;
d2 = x;
value(d2) = x;
word0(d2) -= 31*Exp_msk1; /* adjust exponent */
i -= (Bias + (P-1) - 1) + 1;
denorm = 1;
}
#endif
ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
ds = (value(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 (d < tens[k])
if (value(d) < tens[k])
k--;
k_check = 0;
}
@ -2130,7 +2146,7 @@ __dtoa
/* Try to get by with floating-point arithmetic. */
i = 0;
d2 = d;
value(d2) = value(d);
k0 = k;
ilim0 = ilim;
ieps = 2; /* conservative */
@ -2140,7 +2156,7 @@ __dtoa
if (j & Bletch) {
/* prevent overflows */
j &= Bletch - 1;
d /= bigtens[n_bigtens-1];
value(d) /= bigtens[n_bigtens-1];
ieps++;
}
for(; j; j >>= 1, i++)
@ -2148,32 +2164,32 @@ __dtoa
ieps++;
ds *= bigtens[i];
}
d /= ds;
value(d) /= ds;
}
else if (j1 = -k) {
d *= tens[j1 & 0xf];
value(d) *= tens[j1 & 0xf];
for(j = j1 >> 4; j; j >>= 1, i++)
if (j & 1) {
ieps++;
d *= bigtens[i];
value(d) *= bigtens[i];
}
}
if (k_check && d < 1. && ilim > 0) {
if (k_check && value(d) < 1. && ilim > 0) {
if (ilim1 <= 0)
goto fast_failed;
ilim = ilim1;
k--;
d *= 10.;
value(d) *= 10.;
ieps++;
}
eps = ieps*d + 7.;
value(eps) = ieps*value(d) + 7.;
word0(eps) -= (P-1)*Exp_msk1;
if (ilim == 0) {
S = mhi = 0;
d -= 5.;
if (d > eps)
value(d) -= 5.;
if (value(d) > value(eps))
goto one_digit;
if (d < -eps)
if (value(d) < -value(eps))
goto no_digits;
goto fast_failed;
}
@ -2182,33 +2198,33 @@ __dtoa
/* Use Steele & White method of only
* generating digits needed.
*/
eps = 0.5/tens[ilim-1] - eps;
value(eps) = 0.5/tens[ilim-1] - value(eps);
for(i = 0;;) {
L = d;
d -= L;
L = value(d);
value(d) -= L;
*s++ = '0' + (int)L;
if (d < eps)
if (value(d) < value(eps))
goto ret1;
if (1. - d < eps)
if (1. - value(d) < value(eps))
goto bump_up;
if (++i >= ilim)
break;
eps *= 10.;
d *= 10.;
value(eps) *= 10.;
value(d) *= 10.;
}
}
else {
#endif
/* Generate ilim digits, then fix them up. */
eps *= tens[ilim-1];
for(i = 1;; i++, d *= 10.) {
L = d;
d -= L;
value(eps) *= tens[ilim-1];
for(i = 1;; i++, value(d) *= 10.) {
L = value(d);
value(d) -= L;
*s++ = '0' + (int)L;
if (i == ilim) {
if (d > 0.5 + eps)
if (value(d) > 0.5 + value(eps))
goto bump_up;
else if (d < 0.5 - eps) {
else if (value(d) < 0.5 - value(eps)) {
while(*--s == '0');
s++;
goto ret1;
@ -2221,7 +2237,7 @@ __dtoa
#endif
fast_failed:
s = s0;
d = d2;
value(d) = value(d2);
k = k0;
ilim = ilim0;
}
@ -2233,24 +2249,24 @@ __dtoa
ds = tens[k];
if (ndigits < 0 && ilim <= 0) {
S = mhi = 0;
if (ilim < 0 || d <= 5*ds)
if (ilim < 0 || value(d) <= 5*ds)
goto no_digits;
goto one_digit;
}
for(i = 1;; i++) {
L = d / ds;
d -= L*ds;
L = value(d) / ds;
value(d) -= L*ds;
#ifdef Check_FLT_ROUNDS
/* If FLT_ROUNDS == 2, L will usually be high by 1 */
if (d < 0) {
if (value(d) < 0) {
L--;
d += ds;
value(d) += ds;
}
#endif
*s++ = '0' + (int)L;
if (i == ilim) {
d += d;
if (d > ds || d == ds && L & 1) {
value(d) += value(d);
if (value(d) > ds || value(d) == ds && L & 1) {
bump_up:
while(*--s == '9')
if (s == s0) {
@ -2262,7 +2278,7 @@ __dtoa
}
break;
}
if (!(d *= 10.))
if (!(value(d) *= 10.))
break;
}
goto ret1;


Loading…
Cancel
Save