Namespaces
Variants

std:: remquo, std:: remquof, std:: remquol

From ja.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 remquo ( float x, float y, int * quo ) ;

double remquo ( double x, double y, int * quo ) ;

long double remquo ( long double x, long double y, int * quo ) ;
(C++11以降)
(C++23以前)
constexpr /* floating-point-type */

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

/* floating-point-type */ y, int * quo ) ;
(C++23以降)
float remquof ( float x, float y, int * quo ) ;
(2) (C++11以降)
(C++23以降constexpr)
long double remquol ( long double x, long double y, int * quo ) ;
(3) (C++11以降)
(C++23以降constexpr)
ヘッダーで定義 <cmath>
template < class Arithmetic1, class Arithmetic2 >

/* common-floating-point-type */

remquo ( Arithmetic1 x, Arithmetic2 y, int * quo ) ;
(A) (C++11以降)
(C++23以降constexpr)
1-3) 除算演算 x / y の浮動小数点剰余を std::remainder() 関数と同様に計算する。さらに、 x / y の符号と少なくとも下位3ビットが quo に格納され、これにより結果の周期内でのオクタントを決定するのに十分な情報が得られる。 ライブラリは、すべてのcv修飾されていない浮動小数点型について、パラメータ x と y の型として std::remquo のオーバーロードを提供する。 (C++23以降)
A) その他の算術型のすべての組み合わせに対して、追加のオーバーロードが提供されています。

目次

パラメータ

x, y - 浮動小数点または整数値
quo - int へのポインタで、 x / y の符号と一部のビットを格納する

戻り値

成功した場合、x/yの除算の浮動小数点剰余を std::remainder で定義されている通りに返し、 *quo に x/y の符号と少なくとも下位3ビットの情報を格納する (形式的には、 x/y の符号と同じ符号を持ち、その大きさが 2n
を法として x/y の整数商の大きさと合同な値を格納する。ここで n は3以上の実装定義の整数である)。

y がゼロの場合、 * quo に格納される値は未定義です。

定義域エラーが発生した場合、実装定義の値が返されます(NaNがサポートされている場合はNaN)。

アンダーフローによる範囲エラーが発生した場合、サブノーマルがサポートされている場合は正しい結果が返されます。

y がゼロであるが、定義域エラーが発生しない場合、ゼロが返されます。

エラーハンドリング

エラーは math_errhandling で指定された通りに報告されます。

y がゼロの場合、定義域エラーが発生する可能性があります。

IEEE浮動小数点演算(IEC 60559)を実装がサポートしている場合、

  • 現在の 丸めモード は効果を持ちません。
  • FE_INEXACT は決して発生しません。
  • x が±∞で、 y がNaNでない場合、NaNが返され、 FE_INVALID が発生します。
  • y が±0で、 x がNaNでない場合、NaNが返され、 FE_INVALID が発生します。
  • x または y のいずれかがNaNの場合、NaNが返されます。

注記

POSIXでは 、 x が無限大または y がゼロの場合、定義域エラーが発生することが要求されています。

この関数は、周期が浮動小数点値として正確に表現可能な周期関数を実装する際に有用です:非常に大きな x に対して sin(πx) を計算する場合、 std::sin を直接呼び出すと大きな誤差が生じる可能性がありますが、関数引数を最初に std::remquo で還元すると、商の下位ビットを使用して周期内の結果の符号とオクタントを決定できる一方、剰余を使用して高精度で値を計算できます。

一部のプラットフォームでは、この演算はハードウェアでサポートされています(例えば、Intel CPUでは、 FPREM1 は完了時に商の精度を正確に3ビット残します)。

追加のオーバーロードは (A) と完全に同一である必要はありません。それらは、第一引数 num1 と第二引数 num2 について以下を保証するのに十分であればよいのです:

  • num1 または num2 の型が long double の場合、 std :: remquo ( num1, num2, quo ) は std :: remquo ( static_cast < long double > ( num1 ) ,
    static_cast < long double > ( num2 ) , quo )
    と同じ効果を持つ。
  • それ以外の場合、 num1 および/または num2 の型が double または整数型の場合、 std :: remquo ( num1, num2, quo ) は std :: remquo ( static_cast < double > ( num1 ) ,
    static_cast < double > ( num2 ) , quo )
    と同じ効果を持つ。
  • それ以外の場合、 num1 または num2 の型が float の場合、 std :: remquo ( num1, num2, quo ) は std :: remquo ( static_cast < float > ( num1 ) ,
    static_cast < float > ( num2 ) , quo )
    と同じ効果を持つ。
(C++23以前)

num1 と num2 が算術型を持つ場合、 std :: remquo ( num1, num2, quo ) は std :: remquo ( static_cast < /*common-floating-point-type*/ > ( num1 ) ,
static_cast < /*common-floating-point-type*/ > ( num2 ) , quo )
と同じ効果を持つ。ここで /*common-floating-point-type*/ は num1 と num2 の型の間で最大の 浮動小数点変換ランク と最大の 浮動小数点変換サブランク を持つ浮動小数点型であり、整数型の引数は double と同じ浮動小数点変換ランクを持つと見なされる。

そのような最大のランクとサブランクを持つ浮動小数点型が存在しない場合、 オーバーロード解決 は提供されたオーバーロードから使用可能な候補を結果として生成しない。

(C++23以降)

例

#include <cfenv>
#include <cmath>
#include <iostream>
#ifndef __GNUC__
#pragma STDC FENV_ACCESS ON
#endif
const double pi = std::acos(-1); // または C++20 以降では std::numbers::pi
double cos_pi_x_naive(double x)
{
    return std::cos(pi * x);
}
// 周期は2、(0;0.5)で正、(0.5;1.5)で負、(1.5,2)で正の値を取る
double cos_pi_x_smart(double x)
{
    int quadrant;
    double rem = std::remquo(x, 1, &quadrant);
    quadrant = static_cast<unsigned>(quadrant) % 2; // 周期は2
    return quadrant == 0 ?  std::cos(pi * rem)
                         : -std::cos(pi * rem);
}
int main()
{
    std::cout << std::showpos
              << "naive:\n"
              << "  cos(pi * 0.25) = " << cos_pi_x_naive(0.25) << '\n'
              << "  cos(pi * 1.25) = " << cos_pi_x_naive(1.25) << '\n'
              << "  cos(pi * 2.25) = " << cos_pi_x_naive(2.25) << '\n'
              << "smart:\n"
              << "  cos(pi * 0.25) = " << cos_pi_x_smart(0.25) << '\n'
              << "  cos(pi * 1.25) = " << cos_pi_x_smart(1.25) << '\n'
              << "  cos(pi * 2.25) = " << cos_pi_x_smart(2.25) << '\n'
              << "naive:\n"
              << "  cos(pi * 1000000000000.25) = "
              << cos_pi_x_naive(1000000000000.25) << '\n'
              << "  cos(pi * 1000000000001.25) = "
              << cos_pi_x_naive(1000000000001.25) << '\n'
              << "smart:\n"
              << "  cos(pi * 1000000000000.25) = "
              << cos_pi_x_smart(1000000000000.25) << '\n'
              << "  cos(pi * 1000000000001.25) = "
              << cos_pi_x_smart(1000000000001.25) << '\n';
    // エラー処理
    std::feclearexcept(FE_ALL_EXCEPT);
    int quo;
    std::cout << "remquo(+Inf, 1) = " << std::remquo(INFINITY, 1, &quo) << '\n';
    if (fetestexcept(FE_INVALID))
        std::cout << "  FE_INVALID が発生\n";
}

出力例:

naive:
  cos(pi * 0.25) = +0.707107
  cos(pi * 1.25) = -0.707107
  cos(pi * 2.25) = +0.707107
smart:
  cos(pi * 0.25) = +0.707107
  cos(pi * 1.25) = -0.707107
  cos(pi * 2.25) = +0.707107
naive:
  cos(pi * 1000000000000.25) = +0.707123
  cos(pi * 1000000000001.25) = -0.707117
smart:
  cos(pi * 1000000000000.25) = +0.707107
  cos(pi * 1000000000001.25) = -0.707107
remquo(+Inf, 1) = -nan
  FE_INVALID raised

関連項目

整数除算の商と余りを計算する
(関数)
(C++11) (C++11)
浮動小数点除算操作の余り
(関数)
(C++11) (C++11) (C++11)
除算操作の符号付き余り
(関数)