/* Copyright 1982, 1983 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /*char *version "@(#)atof.c 1.3 12/29/83";*/ /* * Ascii String to IEEE Floating Point Routine : * IEEE Standard Single Precision Representation Floating Point * * float * atof(buf) * char *buf; * * No more than 9 significant digits are allowed in single precision. * Largest positive number is 3.4 * 10^33 and the smallest positive * number is 1.2 * 10^-38. * Rely's on the fact that a long and a float are both 32 bits. */ #define BIAS 127L #define EXPSIZ 4 #define FRACSIZ 20 long fptoieee(); float strbin(); float power10(); long atof(buf) char *buf; { char ibuf[FRACSIZ], ebuf[EXPSIZ]; register char *ip, *ep; long ieee; /* return value */ int dp, esign, isign, ebin, places; float ibin, fp; ip = ibuf; ep = ebuf; dp = 0; places = 0L; while (*buf == ' ' || *buf == '\t') /* ignore white spaces */ buf++; isign = (*buf == '-'); if (*buf == '-' || *buf == '+') buf++; while (*buf && *buf != 'e' && *buf != 'E') { if (*buf == '.') dp++; else { /* digit seen */ *ip++ = *buf; if (dp) places++; } buf++; } *ip = 0; if (*buf == 'e' || *buf == 'E') { /* exponent string */ buf++; esign = (*buf == '-'); if (*buf == '-' || *buf == '+') buf++; while (*buf) /* get exponent string */ *ep++ = *buf++; } *ep = 0; ibin = strbin(ibuf); ebin = atoi(ebuf); places = (esign) ? -ebin - places : ebin - places; fp = ibin * power10(places); ieee = fptoieee(fp); if (isign) /* negative float */ ieee =| 0x80000000; return( ieee ); } float power10(pwr) /* 10^pwr */ int pwr; { float f; if (pwr < 0L) /* negative power */ for (f = 1.0; pwr < 0; pwr++) f = f / 10.0; else /* positive power */ for (f = 1.0; pwr > 0; pwr--) f = f * 10.0; return(f); } long fptoieee(f) /* convert current machine float to ieee rep */ float f; /* unsigned float... */ { register long exp, l; if (f == 0.0) return(0L); exp = 0L; for( ; f >= 2.0; f = f / 2.0) exp++; for( ; f < 1.0; f = f * 2.0) exp--; f = f - 1.0; /* implicit 1, eg. 1.F */ if (f != 0.0) f = f * 8388608.0; /* 2 ^ 23 */ l = f; exp =+ BIAS; l =| ((exp<<23) & 0x7f800000); return(l); } float strbin(p) /* decimal string => binary long */ char *p; { float f; for (f = 0.0; *p >= '0' && *p <= '9'; p++) { f = f * 10.0; f = f + (*p - '0'); } return(f); } 0'); } return(f); } 0'); } return(f); } 0'); } return(f); }