#include #include "string.h" #include double strtod(str, ptr) char *str; char **ptr; { int sign = 1; register char c; register char *s = str; register char *p; register i; int expon, expon_s; double mult, mant, atof(); /* Skip whitespace */ while (isspace(*s)) s++; /* Check for sign */ c = *s; if (c == '+') { sign = 1; s++; } else if (c == '-') { sign = -1; s++; } else if (!isdigit(c)) { /* String has to be one of INF INFINITY NAN(string w/o ')') */ char buf[10]; /* to make a lowercase comparison */ double big = 1000000.0; int slen = strlen(s); (void) strncpy(buf, s, 10); for (p = buf, i=slen; i-- != 0; p++ ) { if (isupper(*p)) *p = tolower(*p); } if (strncmp(buf, "inf", 3) == 0) { if (ptr) *ptr = s+3; return (sign * exp(big)); } else if (strncmp(buf, "infinity",8) == 0) { if (ptr) *ptr = s+8; return (sign * exp(big)); } else if (strncmp(buf, "nan",3) == 0 && *(buf+3) != '(') { if (ptr) *ptr = s+3; return (sign * exp(big)) / exp(big); } else if (strncmp(buf, "nan(", 4) == 0) { /* Rest has to end in ')' and not include ')' */ p = strchr(buf, ')'); if (p == (char *) 0) { /* No closing ')' */ if (ptr) *ptr = str; return 0.0; } if (ptr) *ptr = s + (p + 1 - buf); return exp(big) / exp(big); } } /* To get here: we've got a sign, now need mantissa[+exponent] */ for (mant = 0.0; isdigit(*s);) mant = (mant * 10.0) + (*s++ - '0'); if (*s == '.') { /* Collect fraction */ s++; for ( mult = 0.1; isdigit(*s); mult *= 0.1 ) mant += (*s++ - '0') * mult; } /* Check for exponent character */ c = *s; if (c != 'e' && c != 'E' && c != 'd' && c != 'D') { if (ptr) *ptr = s; return sign * mant; } /* Check for or following exponent character */ c = *(s+1); if (c == '+' || c == '-') { if (!isdigit(*(s+2))) { if (ptr) *ptr = s; return sign * mant; } } else if (!isdigit(c)) { if (ptr) *ptr = s; return sign * mant; } /* Move past exponent character */ s++; /* Check for sign */ switch (*s) { case '+': expon_s = 1; s++; break; case '-': expon_s = -1; s++; break; default: expon_s = 1; } /* Collect exponent */ for (expon = 0; isdigit(*s);) expon = (expon * 10) + (*s++ - '0'); if (expon_s == -1) expon = -expon; if (ptr) *ptr = s; return sign * mant * pow(10.0, (double) expon); }