Spec-Zone.ru › C++

FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD

Определено в заголовочном файле <cfenv>
#define FE_DOWNWARD     /*implementation defined*/
(начиная с C++11)
#define FE_TONEAREST    /*implementation defined*/
(начиная с C++11)
#define FE_TOWARDZERO   /*implementation defined*/
(начиная с C++11)
#define FE_UPWARD       /*implementation defined*/
(начиная с C++11)

Каждая из этих макроконстант раскрывается в неотрицательное целочисленное константное выражение, которое можно использовать с std::fesetround и std::fegetround для указания одного из поддерживаемых режимов округления чисел с плавающей точкой. Реализация может определять дополнительные константы режимов округления в <cfenv>; все они должны начинаться с FE_, за которым следует как минимум одна заглавная буква. Каждая макроконстанта определена только в том случае, если соответствующий режим поддерживается.

Константа Пояснение
FE_DOWNWARD округление к минус бесконечности
FE_TONEAREST округление к ближайшему представимому значению
FE_TOWARDZERO округление к нулю
FE_UPWARD округление к плюс бесконечности

Реализация может поддерживать дополнительные режимы округления.

Текущий режим округления влияет на следующее:

  • результаты арифметических операторов для чисел с плавающей точкой вне константных выражений
double x = 1;
x / 10; // 0.09999999999999999167332731531132594682276248931884765625
     // or 0.1000000000000000055511151231257827021181583404541015625
  • результаты стандартных библиотечных математических функций
std::sqrt(2); // 1.41421356237309492343001693370752036571502685546875
           // or 1.4142135623730951454746218587388284504413604736328125
  • неявные преобразования и приведения из числа с плавающей точкой в число с плавающей точкой
double d = 1 + std::numeric_limits<double>::epsilon();
float f = d; // 1.00000000000000000000000
          // or 1.00000011920928955078125
  • преобразования строк, такие как std::strtod или std::printf
std::stof("0.1"); // 0.0999999940395355224609375
               // or 0.100000001490116119384765625
  • библиотечные функции округления std::nearbyint, std::rint, std::lrint
std::lrint(2.1); // 2 or 3

Текущий режим округления НЕ влияет на следующее:

  • неявные преобразования и приведения из числа с плавающей точкой в целое число (всегда округление к нулю),
  • результаты арифметических операторов для чисел с плавающей точкой в выражениях, вычисляемых во время компиляции (всегда округление к ближайшему),
  • библиотечные функции std::round, std::lround, std::llround, std::ceil, std::floor, std::trunc.

Как и для любой функциональности среды чисел с плавающей точкой, округление гарантируется только при установленном #pragma STDC FENV_ACCESS ON.

Компиляторы, не поддерживающие эту директиву pragma, могут предоставлять собственные средства для поддержки текущего режима округления. Например, в Clang и GCC есть параметр -frounding-math, предназначенный для отключения оптимизаций, которые могли бы изменить смысл кода, чувствительного к режиму округления.

Пример

#include <cfenv>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <string>
// #pragma STDC FENV_ACCESS ON

int main()
{
    std::fesetround(FE_DOWNWARD);
    std::cout << "rounding down: \n" << std::setprecision(50)
              << "         pi = " << std::acos(-1.f) << '\n'
              << "stof(\"1.1\") = " << std::stof("1.1") << '\n'
              << "  rint(2.1) = " << std::rint(2.1) << "\n\n";
    std::fesetround(FE_UPWARD);
    std::cout << "rounding up: \n"
              << "         pi = " << std::acos(-1.f) << '\n'
              << "stof(\"1.1\") = " << std::stof("1.1") << '\n'
              << "  rint(2.1) = " << std::rint(2.1) << '\n';
}

Вывод:

rounding down:
         pi = 3.141592502593994140625
stof("1.1") = 1.099999904632568359375
  rint(2.1) = 2

rounding up:
         pi = 3.1415927410125732421875
stof("1.1") = 1.10000002384185791015625
  rint(2.1) = 3

См. также

float_round_style
указывает режимы округления чисел с плавающей точкой
(перечисление)
fegetroundfesetround
(C++11)(C++11)
получает или задаёт направление округления
(функция)
Документация по C для макросов округления чисел с плавающей точкой

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

Spec-Zone.ru

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