double and stringstream formatting

前端 未结 4 1460
半阙折子戏
半阙折子戏 2021-02-19 08:39
double val = 0.1;
std::stringstream ss;
ss << val;
std::string strVal= ss.str();

In the Visual Studio debugger, val has the value 0.

相关标签:
4条回答
  • 2021-02-19 08:50

    For anyone who gets "error: ‘setprecision’ is not a member of ‘std’" you must #include <iomanip> else setprecision(17) will not work!

    0 讨论(0)
  • 2021-02-19 08:55

    There are two issues you have to consider. The first is the precision parameter, which defaults to 6 (but which you can set to whatever you like). The second is what this parameter means, and that depends on the format option you are using: if you are using fixed or scientific format, then it means the number of digits after the decimal (which in turn has a different effect on what is usually meant by precision in the two formats); if you are using the default precision, however (ss.setf( std::ios_base::fmtflags(), std::ios_base::formatfield ), it means the number of digits in the output, regardless of whether the output was actually formatted using scientific or fixed notation. This explains why your display is 12.1231, for example; you're using both the default precision and the default formattting.

    You might want to try the following with different values (and maybe different precisions):

    std::cout.setf( std::ios_base::fmtflags(), std::ios_base::floatfield );
    std::cout << "default:    " << value[i] << std::endl;
    std::cout.setf( std::ios_base::fixed, std::ios_base::floatfield );
    std::cout << "fixed:      " << value[i] << std::endl;
    std::cout.setf( std::ios_base::scientific, std::ios_base::floatfield );
    std::cout << "scientific: " << value[i] << std::endl;
    

    Seeing the actual output will probably be clearer than any detailed description:

    default:    0.1
    fixed:      0.100000
    scientific: 1.000000e-01
    
    0 讨论(0)
  • 2021-02-19 09:08

    The problem occurs at the stream insertion ss << 0.1; rather than at the conversion to string. If you want non-default precision you need to specify this prior to inserting the double:

    ss << std::setprecision(17) << val;
    

    On my computer, if I just use setprecision(16) I still get "0.1" rather than "0.10000000000000001". I need a (slightly bogus) precision of 17 to see that final 1.

    Addendum
    A better demonstration arises with a value of 1.0/3.0. With the default precision you get a string representation of "0.333333". This is not the string equivalent of a double precision 1/3. Using setprecision(16) makes the string "0.3333333333333333"; a precision of 17 yields "0.33333333333333331".

    0 讨论(0)
  • 2021-02-19 09:09

    You can change the floating-point precision of a stringstream as follows:

    double num = 2.25149;
    std::stringstream ss(stringstream::in | stringstream::out);
    ss << std::setprecision(5) << num << endl;
    ss << std::setprecision(4) << num << endl;
    

    Output:

    2.2515
    2.251
    

    Note how the numbers are also rounded when appropriate.

    0 讨论(0)
提交回复
热议问题