std:: round, std:: roundf, std:: roundl, std:: lround, std:: lroundf, std:: lroundl, std:: llround, std:: llroundf
|
Определено в заголовке
<cmath>
|
||
|
Округление до типов с плавающей точкой
|
||
| (1) | ||
|
float
round
(
float
num
)
;
double
round
(
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
)
;
|
(начиная с C++11)
(до C++23) |
|
|
constexpr
long
lround
(
/* floating-point-type */
num
)
;
|
(начиная с C++23) | |
|
long
lroundf
(
float
num
)
;
|
(5) |
(начиная с C++11)
(constexpr начиная с C++23) |
|
long
lroundl
(
long
double
num
)
;
|
(6) |
(начиная с C++11)
(constexpr начиная с C++23) |
|
Округление до
long
long
|
||
| (7) | ||
|
long
long
llround
(
float
num
)
;
long
long
llround
(
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>
|
||
|
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) |
std::round
для всех cv-неквалифицированных типов с плавающей запятой в качестве типа параметра
num
.
(начиная с C++23)
std::lround
и
std::llround
для всех cv-неквалифицированных типов с плавающей точкой в качестве типа параметра
num
.
(начиная с C++23)
Содержание |
Параметры
| 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 возбуждается и возвращается определяемое реализацией значение.
Примечания
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 был поднят
Смотрите также
|
(C++11)
(C++11)
|
ближайшее целое число, не превышающее заданное значение
(функция) |
|
(C++11)
(C++11)
|
ближайшее целое число, не меньшее заданного значения
(функция) |
|
(C++11)
(C++11)
(C++11)
|
ближайшее целое число, не превышающее по модулю заданное значение
(функция) |
|
Документация C
для
round
|
|