From: ceriel Date: Thu, 11 Aug 1988 12:49:06 +0000 (+0000) Subject: Added strtod.c, use it in atof X-Git-Tag: release-5-5~2930 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=ebfc4a15a4067c580d92696b29e17df2a0439fea;p=ack.git Added strtod.c, use it in atof --- diff --git a/lang/cem/libcc/gen/LIST b/lang/cem/libcc/gen/LIST index 97fac09bd..cbb4adf9f 100644 --- a/lang/cem/libcc/gen/LIST +++ b/lang/cem/libcc/gen/LIST @@ -1,6 +1,7 @@ tail_cc.2g.a abs.c atof.c +strtod.c atoi.c atol.c bcmp.c diff --git a/lang/cem/libcc/gen/atof.c b/lang/cem/libcc/gen/atof.c index 256db5e85..80f84bac6 100644 --- a/lang/cem/libcc/gen/atof.c +++ b/lang/cem/libcc/gen/atof.c @@ -1,81 +1,12 @@ /* $Header$ */ #ifndef NOFLOAT -#include -extern double ldexp(); +extern double strtod(); double atof(p) register char *p; { - register int c; - int exp = 0, sign = 1, expsign = 0; - double fl; - double big = (double)(1L << 30) * (1L << 22); - - while (isspace(*p)) p++; - c = *p; - - switch (c) { - case '-': - sign = -1; - case '+': - p++; - } - - fl = 0.0; - while (isdigit(c = *p++)) { - if (fl < big) - fl = 10.0 * fl + (double)(c - '0'); - else - exp++; - } - if (c == '.') { - while (isdigit(c = *p++)) { - if (fl < big) { - fl = 10.0 * fl + (double) (c - '0'); - exp--; - } - } - } - if (fl == 0) return 0; - if (c == 'E' || c == 'e') { - int exp1 = 0; - int sign = 1; - - switch (*p) { - case '-': - sign = -1; - case '+': - p++; - } - while (isdigit(c = *p++)) { - exp1 = 10 * exp1 + c - '0'; - } - exp += sign * exp1; - } - - if (exp < 0) { - expsign = 1; - exp = -exp; - } - - if (exp != 0) { - int oldexp = exp; - double exp5 = 5.0; - double correction = 1.0; - - while (exp) { - if (exp % 2) correction *= exp5; - exp /= 2; - if (exp != 0) exp5 *= exp5; - } - if (expsign) fl = fl / correction; - else fl = fl * correction; - - fl = ldexp(fl, expsign ? -oldexp : oldexp); - } - - return sign * fl; + return strtod(p, (char **) 0); } #endif diff --git a/lang/cem/libcc/gen/strtod.c b/lang/cem/libcc/gen/strtod.c new file mode 100644 index 000000000..88370ad0e --- /dev/null +++ b/lang/cem/libcc/gen/strtod.c @@ -0,0 +1,97 @@ +/* $Header$ */ +#ifndef NOFLOAT +#include + +extern double ldexp(); + +#define MAX (0x7fffffffL/10) + +double +strtod(p, pp) + register char *p; + char **pp; +{ + register int c; + int exp = 0, sign = 1, expsign = 0; + double fl; + long lowl = 0, highl = 0, pos = 1; + int dotseen = 0; + int digitseen = 0; + + if (pp) *pp = p; + while (isspace(*p)) p++; + c = *p; + + switch (c) { + case '-': + sign = -1; + case '+': + p++; + } + + while (isdigit(c = *p++) || (c == '.' && ! dotseen++)) { + if (c == '.') continue; + digit_seen = 1; + if (highl < MAX) { + highl = (highl << 3) + (highl << 1) + (c - '0'); + } + else if (pos < MAX) { + pos = (pos << 3) + (pos << 1); + lowl = (lowl << 3) + (lowl << 1) + (c - '0'); + } + else exp++; + if (dotseen) exp--; + } + if (! digit_seen) return 0.0; + fl = highl; + if (pos > 1) { + fl = pos * fl + lowl; + } + + if (pp) *pp = p-1; + + if (c == 'E' || c == 'e') { + int exp1 = 0; + int sign = 1; + + switch (*p) { + case '-': + sign = -1; + case '+': + p++; + } + if (isdigit(c = *p)) { + do { + exp1 = 10 * exp1 + c - '0'; + } while (isdigit(c = *++p)); + if (pp) *pp = p; + } + exp += sign * exp1; + } + + if (fl == 0.0) return 0.0; + + if (exp < 0) { + expsign = 1; + exp = -exp; + } + + if (exp != 0) { + int oldexp = exp; + double exp5 = 5.0; + double correction = 1.0; + + while (exp) { + if (exp % 2) correction *= exp5; + exp /= 2; + if (exp != 0) exp5 *= exp5; + } + if (expsign) fl = fl / correction; + else fl = fl * correction; + + fl = ldexp(fl, expsign ? -oldexp : oldexp); + } + + return sign * fl; +} +#endif