非常教程

C参考手册

数值 | Numerics

roundl

在头文件<math.h>中定义

float roundf( float arg );

(1)

(since C99)

double round( double arg );

(2)

(since C99)

long double roundl( long double arg );

(3)

(since C99)

Defined in header <tgmath.h>

#define round( arg )

(4)

(since C99)

Defined in header <math.h>

long lroundf( float arg );

(5)

(since C99)

long lround( double arg );

(6)

(since C99)

long lroundl( long double arg );

(7)

(since C99)

Defined in header <tgmath.h>

#define lround( arg )

(8)

(since C99)

Defined in header <math.h>

long long llroundf( float arg );

(9)

(since C99)

long long llround( double arg );

(10)

(since C99)

long long llroundl( long double arg );

(11)

(since C99)

Defined in header <tgmath.h>

#define llround( arg )

(12)

(since C99)

1-3)计算最接近的整数值arg(以浮点格式),无论当前的舍入模式如何,将距离零的中途情况四舍五入。

5-7,9-11)arg无论当前的舍入模式如何,计算最接近的整数值(以整数格式),从零中途舍入一半。

4,8,12)类型泛型宏:如果arg有一个类型long doubleroundllroundlllroundl被调用。否则,如果arg有整数类型或类型doubleroundlroundllround被调用。否则roundflroundfllroundf叫,分别。

参数

arg

-

浮点值

返回值

如果没有发生错误arg,则返回距离零中途的四舍五入的最近整数值。

返回值

论据

如果发生域错误,则返回实现定义的值。

错误处理

按照math_errhandling中的指定报告错误。

如果返回类型表示的范围lround或结果llround超出范围,则可能会出现域错误或范围错误。

如果实现支持IEEE浮点运算(IEC 60559),对于roundroundfroundl功能:

  • 当前的舍入模式不起作用。
  • 如果arg是±∞,则返回,未修改
  • 如果arg为±0,则返回,未修改
  • 如果arg是NaN,则返回NaN

对于lroundllround功能家庭:

  • FE_INEXACT 从未被提出
  • 当前的舍入模式不起作用。
  • 如果arg是±∞,FE_INVALID则引发并返回实现定义的值
  • 如果舍入的结果超出返回类型的范围,FE_INVALID则会引发并返回实现定义的值
  • 如果arg是NaN,FE_INVALID则引发并返回实现定义的值

笔记

FE_INEXACT可能是(但不要求)round在舍入非整数有限值时引发。

最大的可表示浮点值是所有标准浮点格式中的精确整数,因此round不会自行溢出; 但是intmax_t,当存储在整数变量中时,结果可能会溢出任何整数类型(包括)。

POSIX规定是,所有病例lroundllround提高FE_INEXACT是域错误。

该行为的double版本round如同执行如下:

#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 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");
}

可能的输出:

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轮次函数(p:253)
    • 7.12.9.7地下和地下功能(p:253)
    • 7.25类型通用数学<tgmath.h>(p:373-375)
    • F.10.6.6循环函数(p:527)
    • F.10.6.7基础和基本功能(p:528)
  • C99标准(ISO / IEC 9899:1999):
    • 7.12.9.6轮次函数(p:233)
    • 7.12.9.7理论和实践(p:234)
    • 7.22类型通用数学<tgmath.h>(p:335-337)
    • F.9.6.6循环函数(p:464)
    • F.9.6.7地下和地下功能(p:464)
C

C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。