Spec-Zone.ru › C++

std::rint, std::rintf, std::rintl, std::lrint, std::lrintf, std::lrintl, std::llrint, std::llrintf

Определено в заголовочном файле <cmath>
Округление до типов с плавающей точкой
(1)
float       rint ( float num );
double      rint ( double num );
long double rint ( long double num );
(с C++11)
(до C++23)
/* floating-point-type */ rint( /* floating-point-type */ num );
(с C++23)
float       rintf( float num );
(2) (с C++11)
long double rintl( long double num );
(3) (с C++11)
long
(4)
long lrint ( float num );
long lrint ( double num );
long lrint ( long double num );
(с C++11)
(до C++23)
long lrint ( /* floating-point-type */ num );
(с C++23)
long lrintf( float num );
(5) (с C++11)
long lrintl( long double num );
(6) (с C++11)
long long
(7)
long long llrint ( float num );
long long llrint ( double num );
long long llrint ( long double num );
(с C++11)
(до C++23)
long long llrint ( /* floating-point-type */ num );
(с C++23)
long long llrintf( float num );
(8) (с C++11)
long long llrintl( long double num );
(9) (с C++11)
Дополнительные перегрузки
Определено в заголовочном файле <cmath>
template< class Integer >
double rint( Integer num );
(A) (с C++11)
template< class Integer >
long lrint( Integer num );
(B) (с C++11)
template< class Integer >
long long llrint( Integer num );
(C) (с C++11)
1-3) Округляет аргумент с плавающей точкой num до целого значения (в формате с плавающей точкой), используя текущий режим округления. Библиотека предоставляет перегрузки std::rint для всех типов с плавающей точкой без модификаторов cv в качестве типа параметра num.(с C++23)
4-9) Округляет аргумент с плавающей точкой num до целого значения, используя текущий режим округления. Библиотека предоставляет перегрузки std::lrint и std::llrint для всех типов с плавающей точкой без модификаторов cv в качестве типа параметра num.(с C++23)
A-C) Дополнительные перегрузки предоставляются для всех целочисленных типов, которые обрабатываются как double.

Параметры

num - значение с плавающей точкой или целое число

Возвращаемое значение

Если ошибки не возникли, возвращается ближайшее целое число к значению num, согласно текущему режиму округления.

Обработка ошибок

Ошибки сообщаются, как указано в math_errhandling.

Если результат std::lrint или std::llrint выходит за пределы диапазона, представимого типом возвращаемого значения, может произойти ошибка области определения или ошибка диапазона.

Если реализация поддерживает арифметику с плавающей точкой IEEE (IEC 60559), для функции std::rint:

  • Если num равно ±∞, оно возвращается без изменений.
  • Если num равно ±0, оно возвращается без изменений.
  • Если num равно NaN, возвращается NaN.
Для функций std::lrint и std::llrint:
  • Если num равно ±∞, FE_INVALID возникает, и возвращается значение, определённое реализацией.
  • Если результат округления выходит за пределы диапазона типа возвращаемого значения, FE_INVALID возникает, и возвращается значение, определённое реализацией.
  • Если num равно NaN, FE_INVALID возникает, и возвращается значение, определённое реализацией.

Примечания

POSIX определяет, что все случаи, когда std::lrint или std::llrint поднимают FE_INEXACT являются ошибками области определения.

Как указано в math_errhandling, FE_INEXACT может быть (но не обязано быть на платформах без IEEE с плавающей точкой) поднято std::rint при округление нецелого конечного значения.

Единственное различие между std::rint и std::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::rint отличается от std::round тем, что случаи посередине округляются до чётного значения, а не от нуля.

Дополнительные перегрузки не обязаны предоставляться точно как (A-C). Они должны быть достаточными, чтобы гарантировать, что для своего аргумента 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"
              << "  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';
 
    std::fesetround(FE_DOWNWARD);
    std::cout << "Rounding down:\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'
              << "Rounding down with lrint:\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'
              << "Special values:\n"
              << "  lrint(-0.0) = " << std::lrint(-0.0) << '\n'
              << std::hex << std::showbase
              << "  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) = 4
  rint(-2.3) = -2
  rint(-2.5) = -2
  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
Special values:
  lrint(-0.0) = 0
  lrint(-Inf) = 0x8000000000000000
std::rint(0.1) = 0
std::lrint(LONG_MIN-2048.0) = 0x8000000000000000
  FE_INVALID was raised

См. также

trunctruncftruncl
(C++11)(C++11)(C++11)
ближайшее целое число, не превышающее по величине заданное значение
(функция)
nearbyintnearbyintfnearbyintl
(C++11)(C++11)(C++11)
ближайшее целое число, используя текущий режим округления
(функция)
fegetroundfesetround
(C++11)(C++11)
получает или устанавливает направление округления
(функция)
C документация для rint

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/numeric/math/rint

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API