boost format set maximum precision of floating point

873 Views Asked by At

I have essentially the following:

typedef TFp double;
boost::format fmt("Floating point: %2$f");
TFp v = 0.000000001;
fmt % v;
std::cout << fmt.str();

As per the boost format manual, this outputs 6 digits of precision by default, so showing 0.000000, which my users interpret as 0 (and I can't even blame them for thinking that). I could modify my format string and add a dot and then a number after the dollar sign to fix the number of digits, but this number could vary depending on how large the value in the float is, and because of some peculiarities of my code, the typedef that I have in my example (to double) is sometimes a float, so then I'd have to have a different number in my format string again.

Basically I'm looking for a way to tell boost format 'give me as many digits as necessary to show the value of any floating point type, but not more (i.e., when the value is 0.003, it shouldn't print 0.003000 or whatever).

I would think this to be an obvious thing to do, and it took me reading the documentation very carefully twice to find out it's not the default (as is hinting at in some places), but I can't find a way to do it.

1

There are 1 best solutions below

0
vitaut On

I don't think it's possible with the f format specifier because the latter always produces trailing zeros. However, you could use the g specifier and precision of 17 for double which will strip trailing zeros and don't loose precision (provided IEE754 double). This has an unfortunate side effect of producing more digits than necessary in some cases, for example 0.1 will be formatted as 0.10000000000000001.

If you are not limited to Boost Format, then you could use a formatting facility that gives you the shortest decimal representation. For example, the {fmt} library does this by default:

auto s1 = fmt::format("{}", 0.000000001);
// s1 == "1e-9"
auto s2 = fmt::format("{}", 0.1);
// s2 == "0.1"

Disclaimer: I'm the author of {fmt}.