String to floating point decimal

#include <iostream>
#include <cctype>
#include <cstdlib>
using namespace std;

/*
 *	stof by Jakash3
 *	Converts a string to floating point decimal using
 *	specified floating point type template
 *	The string should be in the form:
 *	[+-]?[0123456789].([.][0123456789]+)?[ ]*([eE][+-]?[0123456789]+)?
 *
 *	Example strings:
 *	25, 3.5, 3.500, 3.5e6, 3.5 e-5, 3.5E5, 3.5E-4, 3.5 e+8
 */
template <typename T>
T stof(const char* s) {
	T val = 0;			/* Integer part */
	T frac = 0;			/* Fractional part */
	bool neg = false;	/* Sign flag */
	
	/* Skip whitespace */
	while (isspace(*s)) s++;
	
	/* Check for sign */
	if (*s == '-') { neg = true; s++; }
	else if (*s == '+') s++;
	
	/* Read integer part */
	while (isdigit(*s))
		val = val * 10 + (*(s++) - '0');
	
	/* Read fractional part */	
	if (*s == '.') {
		T q;
		for (s++; isdigit(*s); s++); s--;
		do {
			q = *s - '0';
			frac = frac / 10 + q / 10;
		} while (isdigit(*(--s)));
		while (isdigit(*(++s))) s++;
	}
	
	/* Skip whitespace */
	while (isspace(*s)) s++;
	
	/* Combine integer and fractional part, and apply sign */
	val += frac;
	if (neg) val *= -1;
	
	/* Process E notation */
	if (*s == 'e' || *s == 'E') {
		int j = atoi(++s);
		if (j == 0) return val;
		for (int i = 0; i != j; (j > 0) ? i++ : i--)
			(j > 0) ? val *= 10 : val *= -10;
	}
	
	return val;
}

int main() {
	float f;
	string s;
	cout << "Enter float: ";
	getline(cin, s);
	cout << "You entered " << stof<float>(s.c_str()) << endl;
}

One thought on “String to floating point decimal

  1. This is interesting to me.
    I have been trying to find (an understandable in X hours) algorithm to do this in C++.
    Cannot use the inbuilt atof etc as I need to convert ascii to >> the _very old_ MBF BASIC floating point format which uses a bit of a different layout for the sign, exponent and mantissa. I understand only too well after so much picking apart code how IEEE and MBF are organised, but how to simply code it taking into account overflows and NANs etc.
    This looks too easy! Like to hear if you took it any further regards overflows and NANs.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: