Namespaces
Variants

remquo, remquof, remquol

From cppreference.net
< c ‎ | numeric ‎ | math
Common mathematical functions
Functions
Basic operations
remquo
(C99)
(C99)
(C99)
(C99) (C99) (C99) (C23)
Maximum/minimum operations
Exponential functions
Power functions
Trigonometric and hyperbolic functions
Nearest integer floating-point
(C99) (C99) (C99)
(C23) (C23) (C23) (C23)
Floating-point manipulation
Narrowing operations
(C23)
(C23)
(C23)
(C23)
(C23)
(C23)
Quantum and quantum exponent
Decimal re-encoding functions
Total order and payload functions
Classification
Error and gamma functions
(C99)
(C99)
(C99)
(C99)
Types
Macro constants
Special floating-point values
Arguments and return values
Error handling
Fast operation indicators
ヘッダーで定義 <math.h>
float remquof ( float x, float y, int * quo ) ;
(1) (C99以降)
double remquo ( double x, double y, int * quo ) ;
(2) (C99以降)
long double remquol ( long double x, long double y, int * quo ) ;
(3) (C99以降)
ヘッダーで定義 <tgmath.h>
#define remquo( x, y, quo )
(4) (C99以降)
1-3) 除算演算 x / y の浮動小数点剰余を remainder() 関数と同様に計算する。さらに、 x / y の符号と少なくとも下位3ビットの情報が quo に格納され、これにより結果が周期内でどの象限(八分円)に属するかを判定するのに十分な情報が得られる。
4) 型総称マクロ: 非ポインタ引数が long double 型の場合、 remquol が呼び出される。それ以外の場合、非ポインタ引数が整数型または double 型の場合、 remquo が呼び出される。それ以外の場合、 remquof が呼び出される。

目次

パラメータ

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

戻り値

成功した場合、 remainder で定義される除算 x / y の浮動小数点剰余を返し、 * quo x / y の符号と少なくとも下位3ビットを格納する(形式的には、符号が x / y の符号と一致し、大きさが x / y の整数商の大きさと 2 n を法として合同な値を格納する。ここで 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) を計算する場合、 sin を直接呼び出すと大きな誤差が生じる可能性がありますが、関数引数を最初に remquo で還元すると、商の下位ビットを使用して周期内の結果の符号とオクタントを決定でき、剰余を使用して高精度で値を計算できます。

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

#include <fenv.h>
#include <math.h>
#include <stdio.h>
#ifndef __GNUC__
#pragma STDC FENV_ACCESS ON
#endif
double cos_pi_x_naive(double x)
{
    const double pi = acos(-1);
    return cos(pi * x);
}
// 周期は2、値は(0;0.5)で正、(0.5;1.5)で負、(1.5,2)で正
double cos_pi_x_smart(double x)
{
    const double pi = acos(-1);
    int extremum;
    double rem = remquo(x, 1, &extremum);
    extremum = (unsigned)extremum % 2; // 最寄りの極値を決定するために1ビットを保持
    return extremum ? -cos(pi * rem) : cos(pi * rem);
}
int main(void)
{
    printf("cos(pi * 0.25) = %f\n", cos_pi_x_naive(0.25));
    printf("cos(pi * 1.25) = %f\n", cos_pi_x_naive(1.25));
    printf("cos(pi * 1000000000000.25) = %f\n", cos_pi_x_naive(1000000000000.25));
    printf("cos(pi * 1000000000001.25) = %f\n", cos_pi_x_naive(1000000000001.25));
    printf("cos(pi * 1000000000000.25) = %f\n", cos_pi_x_smart(1000000000000.25));
    printf("cos(pi * 1000000000001.25) = %f\n", cos_pi_x_smart(1000000000001.25));
    // エラー処理
    feclearexcept(FE_ALL_EXCEPT);
    int quo;
    printf("remquo(+Inf, 1) = %.1f\n", remquo(INFINITY, 1, &quo));
    if (fetestexcept(FE_INVALID))
        puts("    FE_INVALID raised");
}

出力例:

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

参考文献

  • C23規格 (ISO/IEC 9899:2024):
  • 7.12.10.3 remquo関数群 (p: TBD)
  • 7.25 総称数学 <tgmath.h> (p: TBD)
  • F.10.7.3 remquo関数群 (p: TBD)
  • C17規格 (ISO/IEC 9899:2018):
  • 7.12.10.3 remquo関数群 (p: 186)
  • 7.25 総称数学 <tgmath.h> (p: 272-273)
  • F.10.7.3 remquo関数群 (p: 385)
  • C11規格 (ISO/IEC 9899:2011):
  • 7.12.10.3 remquo関数 (p: 255)
  • 7.25 総称数学 <tgmath.h> (p: 373-375)
  • F.10.7.3 remquo関数 (p: 529)
  • C99規格 (ISO/IEC 9899:1999):
  • 7.12.10.3 remquo関数 (p: 236)
  • 7.22 総称数学 <tgmath.h> (p: 335-337)
  • F.9.7.3 remquo関数 (p: 465)

関連項目

整数除算の商と余りを計算する
(関数)
(C99) (C99)
浮動小数点除算演算の余りを計算する
(関数)
浮動小数点除算演算の符号付き余りを計算する
(関数)