/* $Header$ */
#ifndef NOFLOAT
-#include <ctype.h>
-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
--- /dev/null
+/* $Header$ */
+#ifndef NOFLOAT
+#include <ctype.h>
+
+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