Hi i want to round double numbers like this (away from zero) in C++:
4.2 ----> 5
5.7 ----> 6
-7.8 ----> -8
-34.2 ----> -35
What is the efficient way to do this?
Hi i want to round double numbers like this (away from zero) in C++:
4.2 ----> 5
5.7 ----> 6
-7.8 ----> -8
-34.2 ----> -35
What is the efficient way to do this?
inline double myround(double x)
{
return x < 0 ? floor(x) : ceil(x);
}
As mentioned in the article Huppie cites, this is best expressed as a template that works across all float types
See http://en.cppreference.com/w/cpp/numeric/math/floor and http://en.cppreference.com/w/cpp/numeric/math/floor
or, thanks to Pax, a non-function version:
x = (x < 0) ? floor(x) : ceil(x);
There is a nice article about a similar problem on CPlusPlus.com. The easy solution to your problem should be something like this:
double customRound( double value ) const {
return value < 0 ? floor( value ) : ceil( value );
}
A better solution is the one mentioned in the article, which uses a template:
//--------------------------------------------------------------------------
// symmetric round up
// Bias: away from zero
template <typename FloatType>
FloatType ceil0( const FloatType& value )
{
FloatType result = std::ceil( std::fabs( value ) );
return (value < 0.0) ? -result : result;
}
The x < 0 ? floor(x) : ceil(x);
approach of Ruben Bartelink is good. Yet consider what happens with special cases of x = -0.0
, x = NaN
.
Rather than have myround(-0.0)
potentially return +0.0
1 and have myround(NaN)
return with a changed payload of the NaN
, consider the below.
myround_alt(-0.0)
returns -0.0
.
myround_alt(NaN)
more likely returns an unchanged payload NaN. Not-a-number stuff is tricky and not well defined. IAC, it is the myround_alt(-0.0)
--> -0.0
I am seeking.
inline double myround_alt(double x) {
if (x > 0) return ceil(x);
if (x < 0) return floor(x);
return x;
}
1IEC 60559 floating-point arithmetic specifies ceil(±0)
returns ±0
so this approach not needed with implementations that strictly follow that spec. Yet many C floating point implementation do not follow that (C does not require it) or fail in such comer cases like this.
try
double rounded = _copysign(ceil(abs(x)), x);