Namespaces
Variants

std:: fmod, std:: fmodf, std:: fmodl

From ru.cppreference.net
Common mathematical functions
Nearest integer floating point operations
(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 fmod ( float x, float y ) ;

double fmod ( double x, double y ) ;

long double fmod ( long double x, long double y ) ;
(до C++23)
constexpr /*floating-point-type*/

fmod ( /*floating-point-type*/ x,

/*floating-point-type*/ y ) ;
(начиная с C++23)
float fmodf ( float x, float y ) ;
(2) (начиная с C++11)
(constexpr начиная с C++23)
long double fmodl ( long double x, long double y ) ;
(3) (начиная с C++11)
(constexpr начиная с C++23)
Перегрузка SIMD (начиная с C++26)
Определено в заголовке <simd>
template < class V0, class V1 >

constexpr /*math-common-simd-t*/ < V0, V1 >

fmod ( const V0 & v_x, const V1 & v_y ) ;
(S) (начиная с C++26)
Определено в заголовке <cmath>
template < class Integer >
double fmod ( Integer x, Integer y ) ;
(A) (constexpr начиная с C++23)
1-3) Вычисляет остаток от деления с плавающей запятой операции x / y . Библиотека предоставляет перегрузки std::fmod для всех типов с плавающей запятой без cv-квалификаторов в качестве типа параметров. (начиная с C++23)
S) SIMD перегрузка выполняет поэлементное вычисление std::fmod для v_x и v_y .
(См. math-common-simd-t для его определения.)
(since C++26)
A) Дополнительные перегрузки предоставляются для всех целочисленных типов, которые трактуются как double .
(since C++11)

Вещественный остаток от операции деления x / y , вычисляемый данной функцией, точно соответствует значению x - iquot * y , где iquot является результатом x / y с усечённой дробной частью.

Возвращаемое значение имеет тот же знак, что и x и меньше, чем y по величине.

Содержание

Параметры

x, y - значения с плавающей точкой или целочисленные значения

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

В случае успеха возвращает остаток от деления с плавающей запятой x / y как определено выше.

Если происходит ошибка области определения, возвращается значение, определяемое реализацией (NaN, если поддерживается).

Если происходит ошибка диапазона из-за потери значимости (underflow), возвращается корректный результат (после округления).

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

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

Ошибка домена может возникнуть, если y равен нулю.

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

  • Если x равен ±0, а y не равен нулю, возвращается ±0.
  • Если x равен ±∞, а y не является NaN, возвращается NaN и FE_INVALID возбуждается.
  • Если y равен ±0, а x не является NaN, возвращается NaN и FE_INVALID возбуждается.
  • Если y равен ±∞, а x конечен, возвращается x .
  • Если любой аргумент является NaN, возвращается NaN.

Примечания

POSIX требует возникновения ошибки домена, если x является бесконечным или y равен нулю.

std::fmod , но не std::remainder полезен для бесшумного оборачивания типов с плавающей точкой в беззнаковые целочисленные типы: ( 0.0 <= ( y = std :: fmod ( std:: rint ( x ) , 65536.0 ) ) ? y : 65536.0 + y ) находится в диапазоне [ - 0.0 , 65535.0 ] , что соответствует unsigned short , но std:: remainder ( std:: rint ( x ) , 65536.0 находится в диапазоне [ - 32767.0 , + 32768.0 ] , что выходит за пределы диапазона signed short .

Версия double для std::fmod ведёт себя так, как если бы была реализована следующим образом:

double fmod(double x, double y)
{
#pragma STDC FENV_ACCESS ON
    double result = std::remainder(std::fabs(x), y = std::fabs(y));
    if (std::signbit(result))
        result += y;
    return std::copysign(result, x);
}

Выражение x - std:: trunc ( x / y ) * y может не равняться std :: fmod ( x, y ) , когда округление x / y для инициализации аргумента std::trunc теряет слишком много точности (пример: x = 30.508474576271183309 , y = 6.1016949152542370172 ).

Дополнительные перегрузки не обязаны быть предоставлены в точности как (A) . Они должны быть лишь достаточными для обеспечения того, чтобы для их первого аргумента num1 и второго аргумента num2 :

  • Если num1 или num2 имеет тип long double , то std :: fmod ( num1, num2 ) имеет тот же эффект, что и std :: fmod ( static_cast < long double > ( num1 ) ,
    static_cast < long double > ( num2 ) )
    .
  • В противном случае, если num1 и/или num2 имеет тип double или целочисленный тип, то std :: fmod ( num1, num2 ) имеет тот же эффект, что и std :: fmod ( static_cast < double > ( num1 ) ,
    static_cast < double > ( num2 ) )
    .
  • В противном случае, если num1 или num2 имеет тип float , то std :: fmod ( num1, num2 ) имеет тот же эффект, что и std :: fmod ( static_cast < float > ( num1 ) ,
    static_cast < float > ( num2 ) )
    .
(до C++23)

Если num1 и num2 имеют арифметические типы, то std :: fmod ( num1, num2 ) имеет тот же эффект, что и std :: fmod ( static_cast < /*common-floating-point-type*/ > ( num1 ) ,
static_cast < /*common-floating-point-type*/ > ( num2 ) )
, где /*common-floating-point-type*/ - это тип с плавающей точкой с наибольшим рангом преобразования с плавающей точкой и наибольшим подрангом преобразования с плавающей точкой среди типов num1 и num2 , при этом аргументы целочисленного типа считаются имеющими тот же ранг преобразования с плавающей точкой, что и double .

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

(начиная с C++23)

Пример

#include <cfenv>
#include <cmath>
#include <iostream>
// #pragma STDC FENV_ACCESS ON
int main()
{
    std::cout << "fmod(+5.1, +3.0) = " << std::fmod(5.1, 3) << '\n'
              << "fmod(-5.1, +3.0) = " << std::fmod(-5.1, 3) << '\n'
              << "fmod(+5.1, -3.0) = " << std::fmod(5.1, -3) << '\n'
              << "fmod(-5.1, -3.0) = " << std::fmod(-5.1, -3) << '\n';
    // специальные значения
    std::cout << "fmod(+0.0, 1.0) = " << std::fmod(0, 1) << '\n'
              << "fmod(-0.0, 1.0) = " << std::fmod(-0.0, 1) << '\n'
              << "fmod(5.1, Inf) = " << std::fmod(5.1, INFINITY) << '\n';
    // обработка ошибок
    std::feclearexcept(FE_ALL_EXCEPT);
    std::cout << "fmod(+5.1, 0) = " << std::fmod(5.1, 0) << '\n';
    if (std::fetestexcept(FE_INVALID))
        std::cout << "    FE_INVALID raised\n";
}

Возможный вывод:

fmod(+5.1, +3.0) = 2.1
fmod(-5.1, +3.0) = -2.1
fmod(+5.1, -3.0) = 2.1
fmod(-5.1, -3.0) = -2.1
fmod(+0.0, 1.0) = 0
fmod(-0.0, 1.0) = -0
fmod(5.1, Inf) = 5.1
fmod(+5.1, 0) = -nan
    FE_INVALID raised

Смотрите также

вычисляет частное и остаток от целочисленного деления
(функция)
(C++11) (C++11) (C++11)
знаковый остаток от операции деления
(функция)
(C++11) (C++11) (C++11)
знаковый остаток, а также три последних бита операции деления
(функция)
C documentation для fmod