According to ios_base manipulators, I basically have the choice between defaultfloat
and fixed
when formatting floating point numbers without exponent notation (with decimal numbers).
However, I want to choose the maximum precision which would produce a lot trailing zeros for fixed
for many numbers (e.g. 1.
) but avoid ever using the exponent notation. If set to defaultfloat
, it will look right most of the time, unless the value is really really small, yet not 0.
. In that case, the default representation switches to scientific notation on its own, which breaks the receiver of the formatted output (since it has no clue what 2.22045e-16
means.
So, how can I have my pie and eat it, too? That is, non-exponent notation without unnecessary trailing zeroes.
Note: I did not test the effect of the defaultfloat
flag, since my gcc doesn't seem to implement that flag (yet), but I assume it is the default setting which applies without using any flag. I did check the fixed
flag, which does behave as expected.
A simple method would be something like this:
std::string float2string(double f)
{
std::stringstream ss;
ss << std::fixed << std::setprecision(122) << f; // 122 is LARGE, but you may find that really tiny or really large numbers still don't work out...
std::string s = ss.str();
std::string::size_type len = s.length();
int zeros = 0;
while(len > 1 && s[--len] == '0')
zeros++;
if (s[len] == '.') // remove final '.' if number ends with '.'
zeros++;
s.resize(s.length()-zeros);
return s;
}
I have given it some testing. The biggest problem is that it gives a huge number of decimals for some numbers, and things like 0.05 comes out as 0.05000000000000000277555756156289135105907917022705078125
and 0.7 becomes:
0.05000000000000000277555756156289135105907917022705078125
That's because it's not an "exact" number in binary form.
I think the solution is to calculate roughly how many digits you want in the result, by taking the number of integer digits (or floor(log(f)/log(10)+1)) and then subtracting that number from a constant, such as 17, which is the number of digits you can expect from a double. Then remove surplus zeros.
I'll leave that for the moment, as I've got some other stuff to do that I should have started on a little while ago... ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With