Namespaces
Variants

std:: round, std:: roundf, std:: roundl, std:: lround, std:: lroundf, std:: lroundl, std:: llround, std:: llroundf

From cppreference.net
Common mathematical functions
Nearest integer floating point operations
round lround llround
(C++11) (C++11) (C++11)
(C++11)
(C++11)
(C++11) (C++11) (C++11)
Floating point manipulation functions
(C++11) (C++11)
(C++11)
(C++11)
Classification and comparison
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Types
(C++11)
(C++11)
(C++11)
Macro constants
定义于头文件 <cmath>
向浮点类型舍入
(1)
float round ( float num ) ;

double round ( double num ) ;

long double round ( long double num ) ;
(C++11 起)
(C++23 前)
constexpr /* floating-point-type */
round ( /* floating-point-type */ num ) ;
(C++23 起)
float roundf ( float num ) ;
(2) (C++11 起)
(C++23 起为 constexpr)
long double roundl ( long double num ) ;
(3) (C++11 起)
(C++23 起为 constexpr)
long 舍入
(4)
long lround ( float num ) ;

long lround ( double num ) ;

long lround ( long double num ) ;
(C++11 起)
(C++23 前)
constexpr long lround ( /* floating-point-type */ num ) ;
(C++23 起)
long lroundf ( float num ) ;
(5) (C++11 起)
(C++23 起为 constexpr)
long lroundl ( long double num ) ;
(6) (C++11 起)
(C++23 起为 constexpr)
long long 舍入
(7)
long long llround ( float num ) ;

long long llround ( double num ) ;

long long llround ( long double num ) ;
(C++11 起)
(C++23 前)
constexpr long long llround ( /* floating-point-type */ num ) ;
(C++23 起)
long long llroundf ( float num ) ;
(8) (C++11 起)
(C++23 起为 constexpr)
long long llroundl ( long double num ) ;
(9) (C++11 起)
(C++23 起为 constexpr)
定义于头文件 <cmath>
template < class Integer >
double round ( Integer num ) ;
(A) (C++11 起)
(C++23 起为 constexpr)
template < class Integer >
long lround ( Integer num ) ;
(B) (C++11 起)
(C++23 起为 constexpr)
template < class Integer >
long long llround ( Integer num ) ;
(C) (C++11 起)
(C++23 起为 constexpr)
1-3) 计算最接近 num (浮点格式)的整数值,中间情况向远离零的方向舍入,忽略当前舍入模式。 库为所有 cv 未限定浮点类型提供了 std::round 的重载,作为参数 num 的类型。 (C++23 起)
4-9) 计算最接近 num 的整数值(以整数格式),始终将中间情况从零向远离方向舍入,忽略当前舍入模式。 标准库为所有 cv-未限定浮点类型提供了 std::lround std::llround 的重载版本,作为参数 num 的类型。 (C++23 起)
A-C) 为所有整数类型提供了额外的重载,这些类型将被视为 double

目录

参数

num - 浮点数或整数值

返回值

若无错误发生,将返回最接近 num 的整数值,对中间值采用远离零方向的舍入方式。

返回值
math-round away zero.svg
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 异常并返回实现定义的值。

注释

FE_INEXACT 可能在(但不要求必须)对非整数有限值进行舍入时由 std::round 引发。

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

POSIX 标准规定 ,所有 std::lround std::llround 触发 FE_INEXACT 的情况均属于定义域错误。

double 版本的 std::round 其行为如同通过以下方式实现:

#include <cfenv>
#include <cmath>
#pragma STDC FENV_ACCESS ON
double round(double x)
{
    const int save_round = std::fegetround();
    std::fesetround(FE_TOWARDZERO);
    const double result = std::rint(std::copysign(0.5 + std::fabs(x), x));
    std::fesetround(save_round);
    return result;
}

额外的重载并不要求完全按照 (A-C) 的形式提供。它们只需确保对于整数类型的实参 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 <cassert>
#include <cfenv>
#include <cfloat>
#include <climits>
#include <cmath>
#include <iostream>
// #pragma STDC FENV_ACCESS ON
double custom_round(double x)
{
    const int save_round = std::fegetround();
    std::fesetround(FE_TOWARDZERO);
    const double result = std::rint(std::copysign(0.5 + std::fabs(x), x));
    std::fesetround(save_round);
    return result;
}
void test_custom_round()
{
    for (const double x :
        {
            0.0, 0.3,
            0.5 - DBL_EPSILON / 2,
            0.5,
            0.5 + DBL_EPSILON / 2,
            0.7, 1.0, 2.3, 2.5, 2.7, 3.0,
            static_cast<double>(INFINITY)
        })
        assert(round(+x) == custom_round(+x) && round(-x) == custom_round(-x));
}
int main()
{
    test_custom_round();
    std::cout << std::showpos;
    // round
    std::cout << "round(+2.3) = " << std::round(2.3)
              << "  round(+2.5) = " << std::round(2.5)
              << "  round(+2.7) = " << std::round(2.7) << '\n'
              << "round(-2.3) = " << std::round(-2.3)
              << "  round(-2.5) = " << std::round(-2.5)
              << "  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)
              << "  lround(+2.5) = " << std::lround(2.5)
              << "  lround(+2.7) = " << std::lround(2.7) << '\n'
              << "lround(-2.3) = " << std::lround(-2.3)
              << "  lround(-2.5) = " << std::lround(-2.5)
              << "  lround(-2.7) = " << std::lround(-2.7) << '\n';
    std::cout << "lround(-0.0) = " << std::lround(-0.0)  << '\n'
              << "lround(-Inf) = " << std::lround(-INFINITY) << '\n';
    // 错误处理
    std::feclearexcept(FE_ALL_EXCEPT);
    std::cout << "std::lround(LONG_MAX+1.5) = "
              << std::lround(LONG_MAX +

参见

(C++11) (C++11)
不大于给定值的最近整数
(函数)
(C++11) (C++11)
不小于给定值的最近整数
(函数)
(C++11) (C++11) (C++11)
幅度不大于给定值的最近整数
(函数)