Source for ASCII to FLOAT
~Jay Sturges
jsturges at pldote.intel.com
Wed Jul 12 07:39:02 AEST 1989
/*
* Here is a routine written some time ago
* which will perform ASCII to float conversions
*
* Enjoy,
*
* Jay Sturges sun!sacto!pldote!jsturges
*
*/
#include <stdio.h>
#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;
}
}
More information about the Comp.lang.c
mailing list