Question

The output of the following code:

#include <limits>
#include <iostream>
#include <iomanip>
#include <limits>
#include <string>
#include <sstream>

using namespace std;

inline string lexical_cast(const float arg)
{
    stringstream ss;
    ss << fixed << setprecision(numeric_limits<float>::digits10) << arg;
    if (!ss)
        throw "Conversion failed";

    return ss.str();
}

int main()
{
    cout << numeric_limits<float>::digits10 << '\n';
    cout << lexical_cast(32.123456789) << '\n';
}

is:

6
32.123455

I expected, and wanted:

6
32.1234

because, to the best of my knowledge, that's the extent of what a float can reliably give me on my system.

How can I persuade IOStreams to behave as I want?

Was it helpful?

Solution

In fixed-width mode the "precision" setting is used as the number of decimal places, in contrast with scientific mode where it is used as the number of significant digits. IOStreams provides no mechanism to use "precision" as the number of significant digits without using scientific mode.

There is a third mode, which in C++11 is activated with std::defaultfloat. This "default" mode is what you get if you don't set either fixed or scientific mode. You can re-activate it in C++03 by resetting the float flags with s.unsetf(std::ios_base::floatfield). This mode is a bit of a mix between scientific and some sort of "fixed without trailing zeros".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top