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以降)
(constexpr C++23以降)
long double roundl ( long double num ) ;
(3) (C++11以降)
(constexpr C++23以降)
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以降)
(constexpr C++23以降)
long long llroundl ( long double num ) ;
(9) (C++11以降)
(constexpr C++23以降)
<cmath>ヘッダで定義 <cmath>
template < class Integer >
double round ( Integer num ) ;
(A) (C++11以降)
(constexpr C++23以降)
template < class Integer >
long lround ( Integer num ) ;
(B) (C++11以降)
(constexpr C++23以降)
template < class Integer >
long long llround ( Integer num ) ;
(C) (C++11以降)
(constexpr C++23以降)
1-3) num を浮動小数点形式で最も近い整数値に丸め、中間の場合は現在の丸めモードに関わらずゼロから遠ざかる方向に丸めます。 ライブラリは、 std::round のオーバーロードを、パラメータ num の型としてすべてのcv修飾されていない浮動小数点型に対して提供します。 (C++23以降)
4-9) num に最も近い整数値を計算します(整数形式で)。中間の場合は現在の丸めモードに関係なく、ゼロから遠ざかる方向に丸められます。 ライブラリは、 std::lround および std::llround のオーバーロードを、パラメータ num の型としてすべてのcv修飾されていない浮動小数点型に対して提供します。 (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;
    // 丸め処理
    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 + 1.5) << '\n';
    if (std::fetestexcept(FE_INVALID))
        std::cout << "    FE_INVALID が発生しました\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

関連項目

(C++11) (C++11)
指定された値以下の最大の整数
(関数)
(C++11) (C++11)
指定された値以上の最小の整数
(関数)
(C++11) (C++11) (C++11)
絶対値が指定された値以下で最も近い整数
(関数)