SysIII/usr/src/cmd/bs/atof.c

Compare this file to the similar file:
Show the results in this format:

/*
	C library - ascii to floating
*/

#include <stdio.h>
#include <ctype.h>

char *Atof;
double
atof(p) register char *p; {
	register int c;
	register int exp;
	double rv;
	double fl, flexp;
	double big = 72057594037927936.;  /*2^56*/
	double huge = 1.7e38;
	double ten21 = 1e21;
	int neg, negexp, eexp;

	Atof = p;
	neg = 1;
	if (*p == '-')
		++p, neg = -1;
	else if (*p=='+')
		++p;

	exp = 0;
	fl = 0;
	while(c = *p++) {
		if(!isdigit(c))
			break;
		if (fl<big)
			fl = 10*fl + (c-'0');
		else
			exp++;
	}

	if (c == '.') {
		while ((c = *p++), isdigit(c)) {
			if (fl<big) {
				fl = 10*fl + (c-'0');
				exp--;
			}
		}
	}

	negexp = 0;
	eexp = 0;
	if ((c == 'E') || (c == 'e')) {
		if ((c= *p++) == '+')
			;
		else if (c=='-')
			negexp = 1;
		else
			--p;

		while ((c = *p++), isdigit(c)) {
			eexp = 10*eexp+(c-'0');
		}
		if (negexp)
			eexp = -eexp;
		exp = exp + eexp;
	}

	negexp = 0;
	if (exp<0) {
		negexp = 1;
		exp = -exp;
	}

	if (exp == 0) {
		rv = neg*fl;
		goto ret;
	}
	if (exp>38) {
		if (negexp) {
			rv = 0;
			goto ret;
		} else {
			rv = neg*huge;
			goto ret;
		}
	}

	flexp = 1;
	while(exp>0) {
		flexp = 10*flexp;
		exp--;
		if (exp==21) {
			flexp *= ten21;
			exp -= 21;
		}
	}
	if (negexp) {
		fl /= flexp;
		if (flexp<1) 
			fl = 0;
	} else {
		fl *= flexp;
		if (flexp<1)
			fl = huge;
	}
	rv = neg*fl;
ret:
	Atof = --p;
	return rv;
}