Search code examples
c++floating-pointstdrounding

How do you std::round doubles, but round towards zero in halfway cases?


I am in a situation where I need to round 0.5 and -0.5 down to 0. So I checked various documentations -

The generic C++ methods seems always round 0.5 away from 0.

https://en.cppreference.com/w/cpp/numeric/math/round

While if I go the lower level way by setting rounding style, it seems a very global approach and could potentially have threading and CPU state implication which is quite annoying.

https://en.cppreference.com/w/cpp/types/numeric_limits/float_round_style

Is there a light-weight, standard library and simple way to achieve rounding down to 0?


Solution

  • #include <cmath>
    
    template <typename T>
    T absmax(T a, T b)
    {
        return std::abs(a) > std::abs(b) ? a : b;
    }
    
    template <typename T>
    T round_ties_towards_zero(T x)
    {
        return absmax(std::round(std::nextafter(x, T(0))), std::trunc(x));
    }
    

    For sufficiently small numbers you don't need absmax(..., trunc(x)). Without it, I start getting wrong answers for doubles at around 1e16 and larger.