简体   繁体   中英

how to let ss << f work like printf(“%g”, f);

In my C++ program, the initial code is

stringstream ss;
vector<float>::iterator v;
ss << std::left << std::setw(12) << std::setiosflags(std::ios::fixed)
                << std::setprecision(6) << *v;

But for some v , for example, 2345999998888.44445332222 , the output will be very long. So I want that

ss << *v

has the same effect like

printf("%g", f);

and later, I just used ss << *v . Amazingly, the output is the same like %g does.

Does stringstream automatically choose the better way to output a value? Or I just made a tricky mistake?

%g is documented as follows:

converts floating-point number to decimal or decimal exponent notation depending on the value and the precision.

For the g conversion style conversion with style e or f will be performed.

For the G conversion style conversion with style E or F will be performed.

Let P equal the precision if nonzero, 6 if the precision is not specified, or 1 if the precision is ​0 ​. Then, if a conversion with style E would have an exponent of X:

  • if P > X ≥ −4 , the conversion is with style f or F and precision P − 1 − X .

  • otherwise, the conversion is with style e or E and precision P − 1 .

Unless alternative representation is requested the trailing zeros are removed, also the decimal point character is removed if no fractional part is left. For infinity and not-a-number conversion style see notes.

The stream equivalent would look something like this:

#include <cmath>

float f = ...;
int X; // the exponent
int P = 6; // the desired precision

std::frexp(f, &X); 

std::stringstream ss;
if ((P > X) && (X >= −4))
    ss << std::fixed << std::setprecision(P - 1 − X);
else
    ss << std::scientific << std::setprecision(P - 1); 
ss << f;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM