取整
定义于头文件 <cmath>
中。
描述
计算最接近 num
的整数值(浮点格式),半值远离零取整,无论当前的舍入模式如何。
库为所有非 cv 限定的浮点类型提供了 std::round
的重载作为参数 num
的类型 (C++23 起)。
取整到 long 和 取整到 long long 计算最接近 num
的整数值(整数格式),半值远离零取整,无论当前的舍入模式如何。
库为所有非 cv 限定的浮点类型提供了 std::lround
和 std::llround
的重载作为参数 num
的类型 (C++23 起)。
附加重载为所有整数类型提供,这些类型被视为 double。
声明
- C++23
- C++11
// 1)
constexpr /* floating-point-type */
round ( /* floating-point-type */ num );
// 2)
constexpr float roundf( float num );
// 3)
constexpr long double roundl( long double num );
// 4)
constexpr long lround( /* floating-point-type */ num );
// 5)
constexpr long lroundf( float num );
// 6)
constexpr long lroundl( long double num );
// 7)
constexpr long long llround( /* floating-point-type */ num );
// 8)
constexpr long long llroundf( float num );
// 9)
constexpr long long llroundl( long double num );
// 10)
template< class Integer >
constexpr double round( Integer num );
// 11)
template< class Integer >
constexpr long lround( Integer num );
// 12)
template< class Integer >
constexpr long long llround( Integer num );
// 1)
float round ( float num );
// 2)
double round ( double num );
// 3)
long double round ( long double num );
// 4)
float roundf( float num );
// 5)
long double roundl( long double num );
// 6)
long lround ( float num );
// 7)
long lround ( double num );
// 8)
long lround ( long double num );
// 9)
long lroundf( float num );
// 10)
long lroundl( long double num );
// 11)
long long llround ( float num );
// 12)
long long llround ( double num );
// 13)
long long llround ( long double num );
// 14)
long long llroundf( float num );
// 15)
long long llroundl( long double num );
// 16)
template< class Integer >
double round( Integer num );
// 17)
template< class Integer >
long lround( Integer num );
// 18)
template< class Integer >
long long llround( Integer num );
参数
num
- 浮点或整数值
返回值
如果未发生错误,则返回最接近 num
的整数值,半值远离零取整。
如果发生域错误,则返回实现定义的值。
错误处理
错误按 math_errhandling 中指定的方式报告。
如果 std::lround
或 std::llround
的结果超出返回类型可表示的范围,则可能发生域错误或范围错误。
如果实现支持 IEEE 浮点运算(IEC 60559)
对于 std::round
函数
当前的舍入模式无效。
如果 num
是 ±∞
,则返回,不修改
如果 num
是 ±0
,则返回,不修改
如果 num
是 NaN,则返回 NaN
对于 std::lround
和 std::llround
函数
FE_INEXACT 从不引发
当前的舍入模式无效。
如果 num
是 ±∞
,则引发 FE_INVALID 并返回实现定义的值
如果取整结果超出返回类型范围,则引发 FE_INVALID 并返回实现定义的值
如果 num
是 NaN,则引发 FE_INVALID 并返回实现定义的值。
备注
当对非整数有限值进行取整时,std::round
可能会(但不要求)引发 FE_INEXACT。
最大的可表示浮点值在所有标准浮点格式中都是精确整数,因此 std::round
本身从不溢出;但是,当存储在整数变量中时,结果可能会溢出任何整数类型(包括 std::intmax_t
)。
POSIX 规定所有 std::lround
或 std::llround
引发 FE_INEXACT 的情况都是域错误。
std::round
的 double 版本行为仿佛是按如下方式实现的
#include <cfenv>
#include <cmath>
#pragma STDC FENV_ACCESS ON
double round(double x)
{
std::fenv_t save_env;
std::feholdexcept(&save_env);
double result = std::rint(x);
if (std::fetestexcept(FE_INEXACT))
{
auto const save_round = std::fegetround();
std::fesetround(FE_TOWARDZERO);
result = std::rint(std::copysign(0.5 + std::fabs(x), x));
std::fesetround(save_round);
}
std::feupdateenv(&save_env);
return result;
}
附加重载不要求完全按照附加重载提供。它们只需要足以确保对于其整数类型参数 num
std::round(num)
的效果与 std::round(static_cast<double>(num))
相同
std::lround(num)
的效果与 std::lround(static_cast<double>(num))
相同
std::llround(num)
的效果与 std::llround(static_cast<double>(num))
相同
示例
#include <cfenv>
#include <climits>
#include <cmath>
#include <iostream>
// #pragma STDC FENV_ACCESS ON
int main()
{
// round
std::cout
<< "round(+2.3) = "<< std::round(2.3) <<'\n'
<< "round(+2.5) = " << std::round(2.5) <<'\n'
<< "round(+2.7) = "<< std::round(2.7) <<'\n'
<< "round(-2.3) = "<< std::round(-2.3) <<'\n'
<< "round(-2.5) = " << std::round(-2.5) <<'\n'
<< "round(-2.7) = "<< std::round(-2.7) <<'\n';
std::cout
<< "round(-0.0) = "
<< std::round(-0.0) << '\n'
<< "round(-Inf) = "
<< std::round(-INFINITY) << '\n';
// lround
std::cout
<< "lround(+2.3) = "<< std::lround(2.3) <<'\n'
<< "lround(+2.5) = "<< std::lround(2.5) <<'\n'
<< "lround(+2.7) = "<< std::lround(2.7) <<'\n'
<< "lround(-2.3) = "<< std::lround(-2.3) <<'\n'
<< "lround(-2.5) = "<< std::lround(-2.5) <<'\n'
<< "lround(-2.7) = "<< std::lround(-2.7) <<'\n';
std::cout
<< "lround(-0.0) = "
<< std::lround(-0.0) << '\n'
<< "lround(-Inf) = "
<< std::lround(-INFINITY) << '\n';
// error handling
std::feclearexcept(FE_ALL_EXCEPT);
std::cout
<< "std::lround(LONG_MAX+1.5) = "
<< std::lround(LONG_MAX + 1.5) << '\n';
if (std::fetestexcept(FE_INVALID))
std::cout
<< "FE_INVALID was raised\n";
}
round(+2.3) = 2
round(+2.5) = 3
round(+2.7) = 3
round(-2.3) = -2
round(-2.5) = -3
round(-2.7) = -3
round(-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
std::lround(LONG_MAX+1.5) = -9223372036854775808
FE_INVALID was raised