# round, roundf, roundl, lround, lroundf, lroundl, llround, llroundf, llroundl

< c‎ | numeric‎ | math

定义于头文件 `<math.h>` |  |
float roundf( float arg ); | (1) | (C99 起)
double round( double arg ); | (2) | (C99 起)
long double roundl( long double arg ); | (3) | (C99 起)
定义于头文件 `<tgmath.h>` |  |
#define round( arg ) | (4) | (C99 起)
定义于头文件 `<math.h>` |  |
long lroundf( float arg ); | (5) | (C99 起)
long lround( double arg ); | (6) | (C99 起)
long lroundl( long double arg ); | (7) | (C99 起)
定义于头文件 `<tgmath.h>` |  |
#define lround( arg ) | (8) | (C99 起)
定义于头文件 `<math.h>` |  |
long long llroundf( float arg ); | (9) | (C99 起)
long long llround( double arg ); | (10) | (C99 起)
long long llroundl( long double arg ); | (11) | (C99 起)
定义于头文件 `<tgmath.h>` |  |
#define llround( arg ) | (12) | (C99 起)

1-3) 计算与 `arg` 最邻近的整数值（以浮点格式），中点情况取远离零者，无关乎当前舍入模式。
5-7, 9-11) 计算与 `arg` 最邻近的整数值（以整数格式），中点情况取远离零者，无关乎当前舍入模式。
4,8,12) 泛型宏：若 `arg` 拥有 long double 类型，则分别调用 `roundl` 、 `lroundl` 、 `llroundl` 。否则，若 `arg` 拥有整数类型或 double 类型，则分别调用 `round` 、 `lround` 、 `llround` 。否则分别调用 `roundf`, `lroundf`, `llroundf` 。

### 参数

arg | - | 浮点值

### 返回值

若不出现错误，则与返回 `arg` 的最邻近整数值，中点情况取远离零者，

返回值
参数

若出现定义域错误，则返回实现定义值。

### 错误处理

报告 math_errhandling 中指定的错误。

若 `lround` 或 `llround` 的结果在返回类型的可表示范围外，则可能出现定义域错误或值域错误。

若实现支持 IEEE 浮点算术（ IEC 60559 ），

  对于 `round` 、 `roundf` 及 `roundl` 函数：

- 当前舍入模式无效。
- 若 `arg` 为 ±∞ ，则返回不修改的该值
- 若 `arg` 为 ±0 ，则返回不修改的该值
- 若 `arg` 为 NaN ，则返回 NaN

  对于 `lround` 与 `llround` 函数族：

- 决不引发 FE_INEXACT
- 当前舍入模式无效。
- 若 `arg` 为 ±∞ ，则引发 FE_INVALID 并返回实现定义值
- 若舍入结果在返回类型的范围外，则引发 FE_INVALID 并返回实现定义值
- 若 `arg` 为 NaN ，则引发 FE_INVALID 并返回实现定义值

### 注意

`round` 在舍入非整数有限值时，可以（但不要求）引发 FE_INEXACT 。

所有标准浮点格式中，最大可表示浮点值均为准确的整数，故 `round` 自身决不上溢；然而在存储于整数对象时，结果可能溢出任何整数类型（包含 intmax_t ）。

POSIX 指定 `lround` 或 `llround` 引发 FE_INEXACT 的所有情况都是定义域错误。

`round` 的 double 版本如同实现如下：

    #include <math.h>
    #include <fenv.h>
    #pragma STDC FENV_ACCESS ON
    double round(double x)
    {
        fenv_t save_env;
        feholdexcept(&save_env);
        double result = rint(x);
        if (fetestexcept(FE_INEXACT)) {
            fesetround(FE_TOWARDZERO);
            result = rint(copysign(0.5 + fabs(x), x));
        }
        feupdateenv(&save_env);
        return result;
    }

### 示例

    #include <stdio.h>
    #include <math.h>
    #include <fenv.h>
    #include <limits.h>

    #pragma STDC FENV_ACCESS ON

    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));

        // 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 引发

        // 错误处理
        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");
    }

可能的输出：

    round(+2.3) = +2.0  round(+2.5) = +3.0  round(+2.7) = +3.0
    round(-2.3) = -2.0  round(-2.5) = -3.0  round(-2.7) = -3.0
    round(-0.0) = -0.0
    round(-Inf) = -inf
    lround(+2.3) = 2  lround(+2.5) = 3  lround(+2.7) = 3
    lround(-2.3) = -2  lround(-2.5) = -3  lround(-2.7) = -3
    lround(-0.0) = 0
    lround(-Inf) = -9223372036854775808
    lround(LONG_MAX+1.5) = -9223372036854775808
        FE_INVALID was raised

### 引用

- C11 标准（ISO/IEC 9899:2011）：

  - 7.12.9.6 The round functions (p: 253)

  - 7.12.9.7 The lround and llround functions (p: 253)

  - 7.25 Type-generic math <tgmath.h> (p: 373-375)

  - F.10.6.6 The round functions (p: 527)

  - F.10.6.7 The lround and llround functions (p: 528)

- C99 标准（ISO/IEC 9899:1999）：

  - 7.12.9.6 The round functions (p: 233)

  - 7.12.9.7 The lround and llround functions (p: 234)

  - 7.22 Type-generic math <tgmath.h> (p: 335-337)

  - F.9.6.6 The round functions (p: 464)

  - F.9.6.7 The lround and llround functions (p: 464)

### 参阅

floor floorf floorl (C99)(C99) | 计算不大于给定值的最大整数 (函数)
ceil ceilf ceill (C99)(C99) | 计算不小于给定值的最小整数 (函数)
trunc truncf truncl (C99)(C99)(C99) | 取整到绝对值不大于给定值的最接近整数 (函数)