I'm trying to print a max of 4 digits after the decimal point in C++ (Using streams). So if the number does not need 4 digits after the decimal I want it to use only the number of decimals it actually needs.
Examples:
1.12345 -> 1.1234
1.0 -> 1
1.12 -> 1.12
1.12345789 -> 1.1234
123.123 -> 123.123
123.123456 -> 123.1234
I tried std::setprecision(4)
but that sets the number of significant digits and fails in the test case:
123.123456 gives 123.1
I also tried giving std::fixed
along with std::setprecision(4)
but that gives a fixed number of digits after decimal even if not needed:
1.0 gives 1.0000
It seems like std::defaultfloat
is the one I need and not fixed nor exponential. But it does not seem to be printing the number of digits after the decimal appropriately and only has an option for significant digits.
We can do this using a std::stringstream
and a std::string
. We pass the double
to the stream formatting it like we would if we are sending it to cout
. Then we examine the string we get from the stream to see if there are trailing zeros. If there are we get rid of them. Once we do that we check to see if we are left with just a decimal point, if we are then we get rid of that as well. You could use something like this:
int main()
{
double values[] = { 1.12345, 1.0, 1.12, 1.12345789, 123.123, 123.123456, 123456789, 123.001 };
std::vector<std::string> converted;
for (auto e : values)
{
std::stringstream ss;
ss << std::fixed << std::setprecision(4) << e;
std::string value(ss.str());
if (value.find(".") != std::string::npos)
{
// erase trailing zeros
while (value.back() == '0')
value.erase(value.end() - 1);
// if we are left with a . at the end then get rid of it
if (value.back() == '.')
value.erase(value.end() - 1);
converted.push_back(value);
}
else
converted.push_back(value);
}
for (const auto& e : converted)
std::cout << e << "\n";
}
Which when made into a running example gives
1.1235
1
1.12
1.1235
123.123
123.1235
123456789
123.001
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