Search code examples
c++rounding

Round double to 3 points decimal


Currently, I can round a double to an output stream using:

output.setf(std::ios::fixed,std::ios::floatfield);
output.precision(3);

But I'm given a double and I need to make the conversion before I insert it to a vector. So for instance, if the number -0.00078 appears then it equals to 0.000 and I won't need to save it. On the other hand, 1.0009 will become 1.001 (same as the precision function handles it).

How can I convert doubles like that in C++?


Solution

  • A common trick is to do it with math:

    value = std::round(value * 1000.0) / 1000.0;
    

    This scales the value, applies ordinary rounding and then scales it back. You may have some precision loss as is typical with floating-point math, and this won't be effective at extreme ranges of what can be represented by double, but often it's "good enough".

    For something more generalized, put this in a function that accepts rounding to any amount:

    double round_to(double value, double precision = 1.0)
    {
        return std::round(value / precision) * precision;
    }
    

    Example:

    #include <cmath>
    #include <iostream>
    
    double round_to(double value, double precision = 1.0)
    {
        return std::round(value / precision) * precision;
    }
    
    int main()
    {
        double value = 10.0078;
        double precision[] = { 0.001, 0.01, 0.1, 1, 2, 3, 4 };
        for (double p : precision)
        {
            double result = round_to(value, p);
            std::cout << "round_to(" << value << ", " << p << ") = " << result << "\n";
        }
    }
    

    Output:

    round_to(10.0078, 0.001) = 10.008
    round_to(10.0078, 0.01) = 10.01
    round_to(10.0078, 0.1) = 10
    round_to(10.0078, 1) = 10
    round_to(10.0078, 2) = 10
    round_to(10.0078, 3) = 9
    round_to(10.0078, 4) = 12