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;
}