This is kind-of OK with double, less accurate with float. Personally if I want to specify numbers to some fixed precision, I usually use some kind of fixed point notation (integer + divisor).
#include <cmath>
template<class T>
static T Round(T a)
{
static_assert(std::is_floating_point<T>::value, "Round<T>: T must be floating point");
return (a > 0) ? ::floor(a + static_cast<T>(0.5)) : ::ceil(a - static_cast<T>(0.5));
}
template<class T>
static T Round(T a, int places)
{
static_assert(std::is_floating_point<T>::value, "Round<T>: T must be floating point");
const T shift = pow(static_cast<T>(10.0), places);
return Round(a * shift) / shift;
}
int main()
{
auto x = -1000.123;
auto result = Round(x, 3);
}
For double the result of the above is 1000.123000000, with float it's 1000.12299.