I need a simple floating point rounding function, thus:
double round(double);
round(0.1) = 0
round(-0.1) = 0
round(-0.9) = -1
I can find ceil()
and floor()
in the math.h - but not round()
.
Is it present in the standard C++ library under another name, or is it missing??
The C++03 standard relies on the C90 standard for what the standard calls the Standard C Library which is covered in the draft C++03 standard (closest publicly available draft standard to C++03 is N1804) section
1.2
Normative references:If we go to the C documentation for round, lround, llround on cppreference we can see that round and related functions are part of C99 and thus won't be available in C++03 or prior.
In C++11 this changes since C++11 relies on the C99 draft standard for C standard library and therefore provides std::round and for integral return types std::lround, std::llround :
Another option also from C99 would be std::trunc which:
If you need to support non C++11 applications your best bet would be to use boost round, iround, lround, llround or boost trunc.
Rolling your own version of round is hard
Rolling your own is probably not worth the effort as Harder than it looks: rounding float to nearest integer, part 1, Rounding float to nearest integer, part 2 and Rounding float to nearest integer, part 3 explain:
For example a common roll your implementation using
std::floor
and adding0.5
does not work for all inputs:One input this will fail for is
0.49999999999999994
, (see it live).Another common implementation involves casting a floating point type to an integral type, which can invoke undefined behavior in the case where the integral part can not be represented in the destination type. We can see this from the draft C++ standard section
4.9
Floating-integral conversions which says (emphasis mine):For example:
Given
std::numeric_limits<unsigned int>::max()
is4294967295
then the following call:will cause overflow, (see it live).
We can see how difficult this really is by looking at this answer to Concise way to implement round() in C? which referencing newlibs version of single precision float round. It is a very long function for something which seems simple. It seems unlikely that anyone without intimate knowledge of floating point implementations could correctly implement this function:
On the other hand if none of the other solutions are usable newlib could potentially be an option since it is a well tested implementation.
Beware of
floor(x+0.5)
. Here is what can happen for odd numbers in range [2^52,2^53]:This is http://bugs.squeak.org/view.php?id=7134. Use a solution like the one of @konik.
My own robust version would be something like:
Another reason to avoid floor(x+0.5) is given here.
Based on Kalaxy's response, the following is a templated solution that rounds any floating point number to the nearest integer type based on natural rounding. It also throws an error in debug mode if the value is out of range of the integer type, thereby serving roughly as a viable library function.
It may be worth noting that if you wanted an integer result from the rounding you don't need to pass it through either ceil or floor. I.e.,
It's usually implemented as
floor(value + 0.5)
.Edit: and it's probably not called round since there are at least three rounding algorithms I know of: round to zero, round to closest integer, and banker's rounding. You are asking for round to closest integer.
Boost offers a simple set of rounding functions.
For more information, see the Boost documentation.
Edit: Since C++11, there are
std::round
,std::lround
, andstd::llround
.