Sign in to follow this  
MadMax1992

double precision To- and FromString

Recommended Posts

I'm having a small problem with a program that I'm making, I need to have a FromString and ToString function that is able to handle the double-precision floating point numbers. Because the std::stringstream class seems to convert double-precision floating point numbers to single-precision, before converting them. I've created something of a FromString function, it looks like this:
bool CustomFromString(const std::string sVal, double &resval)
{
	//check if value is negative
	bool bNegative;
	std::string s = sVal;

	if (sVal[0] == '-') {
		bNegative = true;
		s.erase(0, 1);
	} else {
		bNegative = false;
	}

	//check for scientific notation
	unsigned int nELocation = s.find('E', 0);
	bool bENegative = false;
	unsigned int nNumLoops = 0;

	if (nELocation == s.npos) {
		nELocation = s.find('e', 0);
	}

	if (nELocation != s.npos) {
		std::string sEPart = s.substr(nELocation, s.length());
		s.erase(nELocation, s.length());

		if (sEPart[1] == '-') {
			bENegative = true;
			sEPart.erase(1, 1);
		}

		if (sEPart.length() < 2) {
			return false;
		}

		nNumLoops += sEPart[1] - '0';

		for (unsigned int i = 2; i < sEPart.length(); i++) {
			nNumLoops *= 10;
			nNumLoops += sEPart[i] - '0';
		}
	}

	//scan for false characters
	unsigned int nCommaCounter = 0;
	unsigned int nECounter = 0;

	for (unsigned int i = 0; i < s.length(); i++) {
		if (s[i] == '.' || s[i] == ',') {
			nCommaCounter++;
		}

		if (s[i] == 'e' || s[i] == 'E') {
			nECounter++;
		}

		if ((s[i] < '0' || s[i] > '9') && s[i] != '.' && s[i] != ',' && s[i] != 'e' && s[i] != 'E') {
			return false;
		}
	}

	if (nCommaCounter > 1) {
		return false;
	}

	if (nECounter > 1) {
		return false;
	}

	if (s.length() <= 0) {
		return false;
	}

	unsigned int nCommaPosition = s.find('.', 0);

	if (nCommaPosition == s.npos) {
		nCommaPosition = s.find(',', 0);
	}


	if (nCommaPosition == s.npos) {
		double dVal = (s[0] - '0');

		for (unsigned int i = 1; i < s.length(); i++) {
			dVal *= 10;
			dVal += (s[i] - '0');
		}

		if (bNegative) {
			resval = -dVal;
		} else {
			resval = dVal;
		}

		for (unsigned int i = 0; i < nNumLoops; i++) {
			if (bENegative) {
				resval /= 10;
			} else {
				resval *= 10;
			}
		}

		return true;
	} else {
		double dValLar = 0;
		double dValSma = 0;

		if (nCommaPosition != 0) {
			dValLar = (s[0] - '0');

			for (unsigned int i = 1; i < nCommaPosition; i++) {
				dValLar *= 10;
				dValLar += (s[i] - '0');
			}
		} else {
			dValLar = 0;
		}

		for (unsigned int i = s.length() - 1; i > nCommaPosition; i--) {
			dValSma += (s[i] - '0');
			dValSma /= 10;
		}

		double dFinal = dValLar + dValSma;

		if (bNegative) {
			resval = -dFinal;
		} else {
			resval = dFinal;
		}

		for (unsigned int i = 0; i < nNumLoops; i++) {
			if (bENegative) {
				resval /= 10;
			} else {
				resval *= 10;
			}
		}
		
		return true;
	}

	return false;
}
I'm just completely stomped by converting a double-precision floating point number to a string. I can't seem to think of a way to do this, help would be much appreciated!

Share this post


Link to post
Share on other sites
Quote:
Because the std::stringstream class seems to convert double-precision floating point numbers to single-precision, before converting them.
Are you sure about that? Are you sure it's not just a display precision issue?

Share this post


Link to post
Share on other sites
Have you looked at the std::ios_base::precision() method? Because I think your real issue is that you aren't setting the right precision for display.

Something like:
std::string doubleToString(double value)
{
std::stringstream ss;
ss.precision(std::numeric_limits<double>::digits10());
// you may need to do use the stringstream::setf() function here, depending on what you want and need.

ss << value;

return ss.str();
}


Though of course I haven't tested this and it may need some modification. I don't know why you made that CustomFromString function either. Try turning up the precision of std::cout when printing your doubles. There may be more than meets the eye.*


*I'm excited for the Transformers movie :)

[edit]

ninja'd++;

Share this post


Link to post
Share on other sites
d'oh!

it would've saved me a lot of time if I knew about the precision method in the stringstream class ;)

It's all fixed, I just needed to convert to From- and ToString functions to this (here for future reference by people with the same problem):


//not sure what the precision of a double-precision
//floating point number is, 20 would be enough, since
//I've read it has 15 significant number

template <typename T>
std::string ToString(T data)
{
std::stringstream ss;
std::string s;
ss.precision(20);
ss << data;
ss >> s;
return s;
}

template <typename T>
bool FromString(const std::string s, T &ResValue)
{
std::istringstream iss;
iss.precision(20);
iss << s;
return !(iss >> std::dec >> ResValue).fail();
}


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this