I have this function:
template<typename T> // T can be float, double or long double
void printAllDigits(T value)
{
std::cout << std::fixed << std::setprecision(999) << value;
}
It's a dumb implementation to print all digits of a floating point value.
This has some problems:
- I can't guarantee that it works for all float types. It seems to work for
float
(999 digits is probably enough), and maybe works fordouble
, but certainly does not work forlong double
(std::numeric_limits<long double>::min()
is printed as "0.", followed by 999 zeros). - It is extremely wasteful, because e.g. for
float
it always prints a ton of trailing zeros, even though those can never be non-zero.
But it does some things right:
- I never want scientific notation, so
std::fixed
makes sense. - I have code that strips the trailing zeros (akin to what is sugessted in Remove trailing zero in C++), which works well with this approach.
- I don't have to write down separate code paths or constants for the different float types.
- If the argument to
setprecision
is large enough, this actually prints all digits without rounding. - I can copy the output, plonk it back into a code file (and make sure to add ".0f" and such where necessary) and get the same floating point value.
- "Unnecessary" digits are not rounded away.
printAllDigits(0.1f)
prints "0.100000001490116119384765625000000...". Printing "0.1" would be sufficient to get back to the originalfloat
value, but I still need the function to print all of those digits.
How can I make that function less wasteful while maintaining my requirements?
std::numeric_limits<T>::max_digits10
is incorrect, since it is too small! std::numeric_limits<float>::min()
gets printed as "0.000000000" instead of "0.0000000000000000000000000000000000000117549435082228750796873653722224567781866555677208752150875170627841725945472717285156250000000..."