Be Careful With Doubles And C++ Streams

I ran across a piece of code recently that was using ostrstream to convert a double to a string. The code looked something like:

std::string DoubleToString(double d) {
    std::ostrstream ostr;
    ostr << d << std::ends;
    std::string str(ostr.str());
    ostr.freeze(false);
    return str;
}

This function was used to convert doubles to strings for insertion into an XML document, which were eventually parsed in an XSLT by the XPath number() function. Most of the time it worked fine, but for really large numbers the number() function failed and return NaN. Why?

The answer is that ostrstream defaulted to printing large doubles in scientific notation. This means that the statement std::cout << DoubleToString(10000000000000000); would print out 1e+016, a string that cannot be not parsed by number(). To fix this, you must tell ostrstream to output the number in fixed notation, as follows:

std::string DoubleToString(double d) {
    std::ostrstream ostr;
    ostr.setf(std::ios::fixed);
    ostr << d << std::ends;
    std::string str(ostr.str());
    ostr.freeze(false);
    return str;
}

About Steven Engelhardt, CFA, AIF
Adjunct Professor of Software Engineering at DePaul University • Software Engineering, Data & Analytics in FinTech • Lives in Chicago, IL

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 )

Google+ photo

You are commenting using your Google+ 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 )

w

Connecting to %s