Sign in to follow this  

double precision To- and FromString

This topic is 3114 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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

This topic is 3114 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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