Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print a max of 4 decimals

Tags:

c++

printing

cout

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.

like image 384
AbdealiJK Avatar asked Dec 19 '16 19:12

AbdealiJK


1 Answers

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
like image 117
NathanOliver Avatar answered Oct 01 '22 17:10

NathanOliver