summaryrefslogtreecommitdiff
path: root/lib/libc/stdlib/strtod.c
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1998-08-12 22:16:39 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1998-08-12 22:16:39 +0000
commit7f4aa2ab6f7c23134089887158694ccd21929b3d (patch)
treee75888c112b741b26b4db3f842d42f6ad58af20c /lib/libc/stdlib/strtod.c
parente54ba284111b6ec7ca7bcce293a73a8e7b0decc6 (diff)
Make code ANSI/ISO C conformant. Formerly undefined constructs were used
making load/store architectures (like mips&alpha) fail whn compiled with gcc -O2.
Diffstat (limited to 'lib/libc/stdlib/strtod.c')
-rw-r--r--lib/libc/stdlib/strtod.c222
1 files changed, 119 insertions, 103 deletions
diff --git a/lib/libc/stdlib/strtod.c b/lib/libc/stdlib/strtod.c
index 4b38110dcb5..36a0603fbfa 100644
--- a/lib/libc/stdlib/strtod.c
+++ b/lib/libc/stdlib/strtod.c
@@ -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;