round, roundf, roundl, lround, lroundf, lroundl, llround, llroundf, llroundl
Header: <math.h>
1-3) Computes the nearest integer value to arg (in floating-point format), rounding halfway cases away from zero, regardless of the current rounding mode.
# Declarations
float roundf( float arg );
(since C99)
double round( double arg );
(since C99)
long double roundl( long double arg );
(since C99)
#define round( arg )
(since C99)
long lroundf( float arg );
(since C99)
long lround( double arg );
(since C99)
long lroundl( long double arg );
(since C99)
#define lround( arg )
(since C99)
long long llroundf( float arg );
(since C99)
long long llround( double arg );
(since C99)
long long llroundl( long double arg );
(since C99)
#define llround( arg )
(since C99)
# Parameters
arg: floating-point value
# Return value
If no errors occur, the nearest integer value to arg, rounding halfway cases away from zero, is returned.
# Notes
FE_INEXACT may be (but isn’t required to be) raised by round when rounding a non-integer finite value.
The largest representable floating-point values are exact integers in all standard floating-point formats, so round never overflows on its own; however the result may overflow any integer type (including intmax_t), when stored in an integer variable.
POSIX specifies that all cases where lround or llround raise FE_INVALID are domain errors.
The double version of round behaves as if implemented as follows:
# Example
#include <assert.h>
#include <fenv.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
// #pragma STDC FENV_ACCESS ON
double custom_round(double x)
{
return signbit(x) ? ceil(x - 0.5) : floor(x + 0.5);
}
void test_custom_round()
{
const double sample[] =
{
0.0, 2.3, 2.5 - DBL_EPSILON, 2.5, 2.5 + DBL_EPSILON, 2.7, INFINITY
};
for (size_t t = 0; t < sizeof sample / sizeof(double); ++t)
assert(round(+sample[t]) == custom_round(+sample[t]) &&
round(-sample[t]) == custom_round(-sample[t]));
}
int main(void)
{
// round
printf("round(+2.3) = %+.1f ", round(2.3));
printf("round(+2.5) = %+.1f ", round(2.5));
printf("round(+2.7) = %+.1f\n", round(2.7));
printf("round(-2.3) = %+.1f ", round(-2.3));
printf("round(-2.5) = %+.1f ", round(-2.5));
printf("round(-2.7) = %+.1f\n", round(-2.7));
printf("round(-0.0) = %+.1f\n", round(-0.0));
printf("round(-Inf) = %+f\n", round(-INFINITY));
test_custom_round();
// lround
printf("lround(+2.3) = %+ld ", lround(2.3));
printf("lround(+2.5) = %+ld ", lround(2.5));
printf("lround(+2.7) = %+ld\n", lround(2.7));
printf("lround(-2.3) = %+ld ", lround(-2.3));
printf("lround(-2.5) = %+ld ", lround(-2.5));
printf("lround(-2.7) = %+ld\n", lround(-2.7));
printf("lround(-0.0) = %+ld\n", lround(-0.0));
printf("lround(-Inf) = %+ld\n", lround(-INFINITY)); // FE_INVALID raised
// error handling
feclearexcept(FE_ALL_EXCEPT);
printf("lround(LONG_MAX+1.5) = %ld\n", lround(LONG_MAX + 1.5));
if (fetestexcept(FE_INVALID))
puts(" FE_INVALID was raised");
}