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

< cpp‎ | numeric‎ | math

定义于头文件 `<cmath>` |  |
| (1) |
float fmod ( float x, float y ); |  |
float fmodf( float x, float y ); |  | (C++11 起)
double fmod ( double x, double y ); | (2) |
| (3) |
long double fmod ( long double x, long double y ); |  |
long double fmodl( long double x, long double y ); |  | (C++11 起)
Promoted fmod ( Arithmetic1 x, Arithmetic2 y ); | (4) | (C++11 起)

1-3) 计算除法运算 x/y 的浮点余数。
4) 所有 1-3 不覆盖的算术类型参数组合的重载集或函数模板。若任何参数拥有整数类型，则将它转型到 double 。若任何其他参数为 long double ，则返回类型是 long double ，否则是 double 。

此函数计算的除法 x/y 的浮点余数是 x - n*y 的准确值，其中 `n` 是截断小数部分的 x/y 。

返回值与 `x` 拥有相同符号，且绝对值小于 `y` 。

### 参数

x, y | - | 浮点值

### 返回值

若成功，则返回定义于上的除法 x/y 的浮点余数。

若出现定义域错误，则返回实现定义值（受支持的平台上为 NaN ）。

若出现下溢所指定值域错误，则返回（舍入后的）正确结果。

### 错误处理

报告 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 的范围外。

`fmod` 的 `double` 版本表现为如同实现如下：

    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/y 到 trunc 的参数损失过多精度时，表达式 x - trunc(x/y)*y 可以不等于 fmod(x,y) （例如： x = 30.508474576271183309, y = 6.1016949152542370172 ）。

### 示例

    #include <iostream>
    #include <cmath>
    #include <cfenv>

    #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

### 参阅

div(int)ldiv lldiv (C++11) | 计算整数除法的商和余数 (函数)
remainder remainderf remainderl (C++11)(C++11)(C++11) | 除法运算的有符号余数 (函数)
remquo remquof remquol (C++11)(C++11)(C++11) | 除法运算的有符号余数和最后三个二进制位 (函数)