跳到主要内容

Rint

定义于头文件 <cmath> 中。

描述

使用当前的舍入模式,将浮点参数 num 舍入为整数值(以浮点格式表示)。
库为所有 cv-unqualified 浮点类型提供了 std::rint 的重载,作为参数 num 的类型  (C++23 起)

舍入为 long舍入为 long long 使用当前的舍入模式,将浮点参数 num 舍入为整数值。
库为所有 cv-unqualified 浮点类型提供了 std::lrintstd::llrint 的重载,作为参数 num 的类型  (C++23 起)

附加重载为所有整数类型提供,这些整数类型被视为 double

声明

// 1)
/* floating-point-type */
rint ( /* floating-point-type */ num );
// 2)
float rintf( float num );
// 3)
long double rintl( long double num );
舍入为 long
// 4)
long lrint( /* floating-point-type */ num );
// 5)
long lrintf( float num );
// 6)
long lrintl( long double num );
舍入为 long long
// 7)
long long llrint( /* floating-point-type */ num );
// 8)
long long llrintf( float num );
// 9)
long long llrintl( long double num );
附加重载
// 10)
template< class Integer >
double rint( Integer num );
// 11)
template< class Integer >
long lrint( Integer num );
// 12)
template< class Integer >
long long llrint( Integer num );

参数

num - 浮点或整数值

返回值

如果未发生错误,则根据当前舍入模式返回最接近 num 的整数值

错误处理

错误按 math_errhandling 中指定的方式报告。

如果 std::lrintstd::llrint 的结果超出返回类型可表示的范围,则可能发生域错误或范围错误。

如果实现支持 IEEE 浮点运算(IEC 60559

对于 std::rint 函数

如果 num±∞,则返回,不修改
如果 num±0,则返回,不修改
如果 num 是 NaN,则返回 NaN

对于 std::lrintstd::llrint 函数

如果 num±∞,则触发 FE_INVALID 并返回一个实现定义的值
如果舍入结果超出返回类型的范围,则触发 FE_INVALID 并返回一个实现定义的值
如果 num 是 NaN,则触发 FE_INVALID 并返回一个实现定义的值

备注

POSIX 规定,所有 std::lrintstd::llrint 触发 FE_INEXACT 的情况都是域错误。

math_errhandling 中所述,当舍入一个非整数有限值时,std::rint 可能会(但非 IEEE 浮点平台不要求)触发 FE_INEXACT。

std::rintstd::nearbyint 之间唯一的区别是 std::nearbyint 从不触发 FE_INEXACT。

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

如果当前舍入模式是

FE_DOWNWARD,则 std::rint 等效于 std::floor。FE_UPWARD,则 std::rint 等效于 std::ceil。FE_TOWARDZERO,则 std::rint 等效于 std::trunc。FE_TONEAREST,则 std::rintstd::round 的区别在于,中间情况会舍入为偶数,而不是远离零。

附加重载不要求完全按照附加重载提供。它们只需要足以确保对于其整数类型参数 num

std::rint(num) 的效果与 std::rint(static_cast<double>(num)) 相同。
std::lrint(num) 的效果与 std::lrint(static_cast<double>(num)) 相同。
std::llrint(num) 的效果与 std::llrint(static_cast<double>(num)) 相同。

示例

#include <cfenv>
#include <climits>
#include <cmath>
#include <iostream>

#pragma STDC FENV_ACCESS ON

int main()
{
std::fesetround(FE_TONEAREST);
std::cout
<< "rounding to nearest (halfway cases to even):\n\n"

<< "rint(+2.3) = "
<< std::rint(2.3) << '\n'
<< " rint(+2.5) = "
<< std::rint(2.5) << '\n'
<< " rint(+3.5) = "
<< std::rint(3.5) << '\n'
<< "rint(-2.3) = "
<< std::rint(-2.3) << '\n'
<< " rint(-2.5) = "
<< std::rint(-2.5) << '\n'
<< " rint(-3.5) = "
<< std::rint(-3.5) << '\n\n';

std::fesetround(FE_DOWNWARD);
std::cout
<< "rounding down:\n\n"

<< "rint(+2.3) = "
<< std::rint(2.3) << '\n'
<< " rint(+2.5) = "
<< std::rint(2.5) << '\n'
<< " rint(+3.5) = "
<< std::rint(3.5) << '\n'
<< "rint(-2.3) = "
<< std::rint(-2.3) << '\n'
<< " rint(-2.5) = "
<< std::rint(-2.5) << '\n'
<< " rint(-3.5) = "
<< std::rint(-3.5) << '\n\n'

<< "rounding down with lrint:\n\n"

<< "lrint(+2.3) = "
<< std::lrint(2.3) << '\n'
<< " lrint(+2.5) = "
<< std::lrint(2.5) << '\n'
<< " lrint(+3.5) = "
<< std::lrint(3.5) << '\n'
<< "lrint(-2.3) = "
<< std::lrint(-2.3) << '\n'
<< " lrint(-2.5) = "
<< std::lrint(-2.5) << '\n'
<< " lrint(-3.5) = "
<< std::lrint(-3.5) << '\n';

std::cout
<< "lrint(-0.0) = "
<< std::lrint(-0.0) << '\n'
<< "lrint(-Inf) = "
<< std::lrint(-INFINITY) << '\n';

// error handling
std::feclearexcept(FE_ALL_EXCEPT);

std::cout
<< "std::rint(0.1) = "
<< std::rint(.1) << '\n';
if (std::fetestexcept(FE_INEXACT))
std::cout
<< "FE_INEXACT was raised\n";

std::feclearexcept(FE_ALL_EXCEPT);

std::cout
<< "std::lrint(LONG_MIN-2048.0) = "
<< std::lrint(LONG_MIN - 2048.0) << '\n';
if (std::fetestexcept(FE_INVALID))
std::cout
<< "FE_INVALID was raised\n";
}

可能结果
rounding to nearest (halfway cases to even): 

rint(+2.3) = 2
rint(+2.5) = 2
rint(+3.5) = 4
rint(-2.3) = -2
rint(-2.5) = -2
rint(-3.5) = -4

rounding down:

rint(+2.3) = 2
rint(+2.5) = 2
rint(+3.5) = 3
rint(-2.3) = -3
rint(-2.5) = -3
rint(-3.5) = -4

rounding down with lrint:

lrint(+2.3) = 2
lrint(+2.5) = 2
lrint(+3.5) = 3
lrint(-2.3) = -3
lrint(-2.5) = -3
lrint(-3.5) = -4
lrint(-0.0) = 0
lrint(-Inf) = -9223372036854775808
std::rint(0.1) = 0
FE_INEXACT was raised
std::lrint(LONG_MIN-2048.0) = -9223372036854775808
FE_INVALID was raised

Rint

定义于头文件 <cmath> 中。

描述

使用当前的舍入模式,将浮点参数 num 舍入为整数值(以浮点格式表示)。
库为所有 cv-unqualified 浮点类型提供了 std::rint 的重载,作为参数 num 的类型  (C++23 起)

舍入为 long舍入为 long long 使用当前的舍入模式,将浮点参数 num 舍入为整数值。
库为所有 cv-unqualified 浮点类型提供了 std::lrintstd::llrint 的重载,作为参数 num 的类型  (C++23 起)

附加重载为所有整数类型提供,这些整数类型被视为 double

声明

// 1)
/* floating-point-type */
rint ( /* floating-point-type */ num );
// 2)
float rintf( float num );
// 3)
long double rintl( long double num );
舍入为 long
// 4)
long lrint( /* floating-point-type */ num );
// 5)
long lrintf( float num );
// 6)
long lrintl( long double num );
舍入为 long long
// 7)
long long llrint( /* floating-point-type */ num );
// 8)
long long llrintf( float num );
// 9)
long long llrintl( long double num );
附加重载
// 10)
template< class Integer >
double rint( Integer num );
// 11)
template< class Integer >
long lrint( Integer num );
// 12)
template< class Integer >
long long llrint( Integer num );

参数

num - 浮点或整数值

返回值

如果未发生错误,则根据当前舍入模式返回最接近 num 的整数值

错误处理

错误按 math_errhandling 中指定的方式报告。

如果 std::lrintstd::llrint 的结果超出返回类型可表示的范围,则可能发生域错误或范围错误。

如果实现支持 IEEE 浮点运算(IEC 60559

对于 std::rint 函数

如果 num±∞,则返回,不修改
如果 num±0,则返回,不修改
如果 num 是 NaN,则返回 NaN

对于 std::lrintstd::llrint 函数

如果 num±∞,则触发 FE_INVALID 并返回一个实现定义的值
如果舍入结果超出返回类型的范围,则触发 FE_INVALID 并返回一个实现定义的值
如果 num 是 NaN,则触发 FE_INVALID 并返回一个实现定义的值

备注

POSIX 规定,所有 std::lrintstd::llrint 触发 FE_INEXACT 的情况都是域错误。

math_errhandling 中所述,当舍入一个非整数有限值时,std::rint 可能会(但非 IEEE 浮点平台不要求)触发 FE_INEXACT。

std::rintstd::nearbyint 之间唯一的区别是 std::nearbyint 从不触发 FE_INEXACT。

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

如果当前舍入模式是

FE_DOWNWARD,则 std::rint 等效于 std::floor。FE_UPWARD,则 std::rint 等效于 std::ceil。FE_TOWARDZERO,则 std::rint 等效于 std::trunc。FE_TONEAREST,则 std::rintstd::round 的区别在于,中间情况会舍入为偶数,而不是远离零。

附加重载不要求完全按照附加重载提供。它们只需要足以确保对于其整数类型参数 num

std::rint(num) 的效果与 std::rint(static_cast<double>(num)) 相同。
std::lrint(num) 的效果与 std::lrint(static_cast<double>(num)) 相同。
std::llrint(num) 的效果与 std::llrint(static_cast<double>(num)) 相同。

示例

#include <cfenv>
#include <climits>
#include <cmath>
#include <iostream>

#pragma STDC FENV_ACCESS ON

int main()
{
std::fesetround(FE_TONEAREST);
std::cout
<< "rounding to nearest (halfway cases to even):\n\n"

<< "rint(+2.3) = "
<< std::rint(2.3) << '\n'
<< " rint(+2.5) = "
<< std::rint(2.5) << '\n'
<< " rint(+3.5) = "
<< std::rint(3.5) << '\n'
<< "rint(-2.3) = "
<< std::rint(-2.3) << '\n'
<< " rint(-2.5) = "
<< std::rint(-2.5) << '\n'
<< " rint(-3.5) = "
<< std::rint(-3.5) << '\n\n';

std::fesetround(FE_DOWNWARD);
std::cout
<< "rounding down:\n\n"

<< "rint(+2.3) = "
<< std::rint(2.3) << '\n'
<< " rint(+2.5) = "
<< std::rint(2.5) << '\n'
<< " rint(+3.5) = "
<< std::rint(3.5) << '\n'
<< "rint(-2.3) = "
<< std::rint(-2.3) << '\n'
<< " rint(-2.5) = "
<< std::rint(-2.5) << '\n'
<< " rint(-3.5) = "
<< std::rint(-3.5) << '\n\n'

<< "rounding down with lrint:\n\n"

<< "lrint(+2.3) = "
<< std::lrint(2.3) << '\n'
<< " lrint(+2.5) = "
<< std::lrint(2.5) << '\n'
<< " lrint(+3.5) = "
<< std::lrint(3.5) << '\n'
<< "lrint(-2.3) = "
<< std::lrint(-2.3) << '\n'
<< " lrint(-2.5) = "
<< std::lrint(-2.5) << '\n'
<< " lrint(-3.5) = "
<< std::lrint(-3.5) << '\n';

std::cout
<< "lrint(-0.0) = "
<< std::lrint(-0.0) << '\n'
<< "lrint(-Inf) = "
<< std::lrint(-INFINITY) << '\n';

// error handling
std::feclearexcept(FE_ALL_EXCEPT);

std::cout
<< "std::rint(0.1) = "
<< std::rint(.1) << '\n';
if (std::fetestexcept(FE_INEXACT))
std::cout
<< "FE_INEXACT was raised\n";

std::feclearexcept(FE_ALL_EXCEPT);

std::cout
<< "std::lrint(LONG_MIN-2048.0) = "
<< std::lrint(LONG_MIN - 2048.0) << '\n';
if (std::fetestexcept(FE_INVALID))
std::cout
<< "FE_INVALID was raised\n";
}

可能结果
rounding to nearest (halfway cases to even): 

rint(+2.3) = 2
rint(+2.5) = 2
rint(+3.5) = 4
rint(-2.3) = -2
rint(-2.5) = -2
rint(-3.5) = -4

rounding down:

rint(+2.3) = 2
rint(+2.5) = 2
rint(+3.5) = 3
rint(-2.3) = -3
rint(-2.5) = -3
rint(-3.5) = -4

rounding down with lrint:

lrint(+2.3) = 2
lrint(+2.5) = 2
lrint(+3.5) = 3
lrint(-2.3) = -3
lrint(-2.5) = -3
lrint(-3.5) = -4
lrint(-0.0) = 0
lrint(-Inf) = -9223372036854775808
std::rint(0.1) = 0
FE_INEXACT was raised
std::lrint(LONG_MIN-2048.0) = -9223372036854775808
FE_INVALID was raised