名前空間
変種
操作

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

From cppreference.com
< cpp‎ | numeric‎ | math
 
 
 
 
ヘッダー <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 /*浮動小数点数型*/

            fmod ( /*浮動小数点型*/ x,

                   /*浮動小数点型*/ y );
(C++23から)
float       fmodf( float x, float y );
(2) (C++11以降)
(C++23 以降 constexpr)
long double fmodl( long double x, long double y );
(3) (C++11以降)
(C++23 以降 constexpr)
ヘッダー <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) (C++23 以降 constexpr)
1-3) 除算操作 x / y の浮動小数点剰余を計算します。ライブラリは、パラメータの型として、すべての cv 修飾されていない浮動小数点型に対する std::fmod のオーバーロードを提供します。(C++23 以降)
S) SIMD オーバーロードは、v_xv_y に対して要素ごとの std::fmod を実行します。
(定義についてはmath-common-simd-tを参照のこと)
(C++26以降)
A) すべての整数型に対する追加のオーバーロードが提供されます。これらは double として扱われます。
(C++11以降)

この関数によって計算される除算操作 x / y の浮動小数点剰余は、iquot が小数点以下を切り捨てた x / y であるような、正確に x - iquot * 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::rint(x), 65536.0) ? y : 65536.0 + y) は範囲 [-0.065535.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 は、x / y の丸めが std::trunc の引数を初期化する際に精度を失いすぎる場合 (x = 30.508474576271183309, y = 6.1016949152542370172 のような場合) 、 std::fmod(x, y) と等しくならない可能性があります。

追加のオーバーロードは (A) とまったく同じように提供される必要はない。それらは、最初の引数 num1 と2番目の引数 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まで)

num1num2 が算術型の場合、std::fmod(num1, num2)std::fmod(static_cast</*共通浮動小数点型*/>(num1),
          static_cast</*共通浮動小数点型*/>(num2))
と同じ効果を持ちます。ここで /*共通浮動小数点型*/ は、num1num2 の型の間で、より大きい 浮動小数点変換ランクとより大きい 浮動小数点変換サブランクを持つ浮動小数点型です。整数型の引数は、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';
 
    // special values
    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';
 
    // error handling
    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)
除算操作における符号付き剰余および商の下位3ビット
(関数) [編集]
English 日本語 中文(简体) 中文(繁體)