| 149 | */ |
| 150 | template <typename T, ARM_COMPUTE_REQUIRES_TA(traits::is_floating_point<T>::value)> |
| 151 | inline T round_half_even(T value, T epsilon = std::numeric_limits<T>::epsilon()) |
| 152 | { |
| 153 | T positive_value = std::abs(value); |
| 154 | T ipart = 0; |
| 155 | std::modf(positive_value, &ipart); |
| 156 | // If 'value' is exactly halfway between two integers |
| 157 | if (std::abs(positive_value - (ipart + 0.5f)) < epsilon) |
| 158 | { |
| 159 | // If 'ipart' is even then return 'ipart' |
| 160 | if (std::fmod(ipart, 2.f) < epsilon) |
| 161 | { |
| 162 | return support::cpp11::copysign(ipart, value); |
| 163 | } |
| 164 | // Else return the nearest even integer |
| 165 | return support::cpp11::copysign(std::ceil(ipart + 0.5f), value); |
| 166 | } |
| 167 | // Otherwise use the usual round to closest |
| 168 | return support::cpp11::copysign(support::cpp11::round(positive_value), value); |
| 169 | } |
| 170 | |
| 171 | /** Round floating-point value given a rounding mode |
| 172 | * |