Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!oliveb!mipos3!pldote!jsturges From: jsturges@pldote.intel.com (~Jay Sturges) Newsgroups: comp.lang.c Subject: Re: Source for ASCII to FLOAT Keywords: atof( ) ASCII float Message-ID: <38@pldote.intel.com> Date: 11 Jul 89 21:39:02 GMT Distribution: usa Organization: Intel, Santa Clara CA Lines: 192 /* * Here is a routine written some time ago * which will perform ASCII to float conversions * * Enjoy, * * Jay Sturges sun!sacto!pldote!jsturges * */ #include #define MAXEXP 38 /* maximum exponent */ #define MINEXP -38 /* minimum exponent */ #define EOL '\0' /* end of line */ #define DOT '.' /* decimal point */ #define TRUE 1 #define FALSE 0 #define CVALUE(c) (c - '0') /* numerical value of char */ typedef char boolean; /* flagging type */ /* * atof( ) * string to double conversion in C language * */ atof(t, value) char *t; real *value; { boolean eflg = FALSE; /* exponetial flag */ boolean dflg = FALSE; /* decimal point flag */ boolean sflg = FALSE; /* sign (+/-) flag */ boolean error = FALSE; /* error case */ real gtvalue = 0; /* value of the string */ real dsign = 1.0; /* sign of the mantissa */ int esign = 1; /* sign of exponetial */ int exp = 0; /* exponetial value */ int didx = 0; /* places after decimal pt. */ int big = 0; /* keeping track of the value */ while (*t != EOL && !error) { switch (*t) { case 'e': /* exponetial flag */ case 'E': /* reset sign flag */ if (eflg) error = TRUE; else { eflg = TRUE; sflg = FALSE; } break; case DOT: /* decimal point flag */ if (dflg) error = TRUE; else { /* * starting counting digits * after decimal point */ dflg = TRUE; didx = 1; } break; case '-': /* sign flag */ case '+': if (sflg) error = TRUE; else { sflg = TRUE; if (!eflg && *t == '-') dsign = -1.0; else if (eflg && *t == '-') esign = -1; } break; case '0': /* unsigned part of the */ case '1': /* exponetial and the */ case '2': /* mantissa. */ case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (eflg) exponetial(*t, &exp); else { if (big >= MAXEXP) error = TRUE; else { mantissa(*t,>value,didx,dflg,&big); if (dflg) didx++; } } break; case ' ': break; default: error = TRUE; } t++; } /* * having the exponetial, the mantissa, the signs of them * the value can be computed, if possible */ if (!error) { /* * signed exponetial and mantissa */ exp *= esign; gtvalue *= dsign; if (exp > MAXEXP || exp < MINEXP || (exp + big) > MAXEXP || (exp + big) < MINEXP) error = TRUE; else if (exp > 0) while (--exp >= 0) gtvalue *= 10.0; else if (exp < 0) while (++exp <= 0) gtvalue *= 0.1; *value = gtvalue; /* * you can exponent zero with any number * and it is still a legal case */ if (*value == 0.0) error = FALSE; } return (error); } /* * basically, atoi() */ static exponetial(c, exp) char c; int *exp; { *exp *= 10; *exp += CVALUE(c); } static mantissa(c, value, didx, decimal, big) char c; real *value; int didx; boolean decimal; int *big; { real dtmp; if (!decimal) { /* * before the decimal point * keeping increasing the value */ *value *= 10.0; *value += (real) CVALUE(c); if (*value > 0.0) (*big)++; } else { /* * after the decimal point */ dtmp = CVALUE(c); if (didx >= MAXEXP) { /* too small, it's virtually zero */ dtmp = 0.0; didx = 0; } while (--didx >= 0) /* C is pass by value */ dtmp *= 0.1; *value += dtmp; } }