/* * a t o f . c * * Ascii to floating */ #ifndef decus #include #endif static double twoe56 = 72057594037927936.; /* 2**56 */ static double exp5[] = { 5., /* 5 ^ 1 */ 25., /* 5 ^ 2 */ 625., /* 5 ^ 4 */ 390625., /* 5 ^ 8 */ 152587890625., /* 5 ^ 16 */ 23232710361480712890625. /* 5 ^ 32 */ }; #define FALSE 0 #define TRUE 1 #ifdef decus double ldexp(value, exp) union { double d; unsigned i; /* High byte has exponent */ } value; int exp; /* * Hack, works only for PDP-11's */ { value.i = (value.i & 0100177) | (((value.i & 0077600) + (exp << 7)) & 077600); return (value.d); } #endif double atof(text) register char *text; /* * Return text as a floating value */ { register int c; /* Current character */ register int exp; /* Exponent */ int eexp; /* ...e exponent */ int bexp; /* for ldexp */ int neg; /* TRUE if negative */ int negexp; /* TRUE if exp negative */ double v; /* Gets value */ double flexp; /* Gets exponent */ exp = 0; v = 0.0; while ((c = *text++) == ' ') ; /* Skip blanks */ if ((neg = (c == '-')) != FALSE) ; else if (c != '+') text--; while ((c = *text++), isdigit(c)) { if (v < twoe56) { v *= 10.0; v += (c - '0'); } else exp++; } if (c == '.') { while ((c = *text++), isdigit(c)) { if (v < twoe56) { v *= 10.0; v += (c - '0'); exp--; } } } if (c == 'e' || c == 'E') { if ((negexp = ((c = *text++) == '-')) != FALSE) ; else if (c != '+') text--; eexp = 0; while ((c = *text++), isdigit(c)) { eexp = (eexp * 10) + (c - '0'); } if (negexp) eexp = -eexp; exp += eexp; } if ((bexp = exp) < 0) exp = -exp; flexp = 1.0; for (c = 0; c < 6; c++) { if (exp & 01) flexp *= exp5[c]; exp >>= 1; if (exp == 0) break; } if (bexp < 0) v /= flexp; else v *= flexp; v = ldexp(v, bexp); if (neg) return (-v); else return (v); } #ifdef TEST #include char text[80]; int $$narg = 1; main() { double v; while (gets(text) != NULL) { v = atof(text); printf("\"%s\" = %g", text, v); printf(", [%o %o %o %o]\n", v); } } #endif