std::remquo, std::remquof, std::remquol
| ヘッダー <cmath> で定義 |
||
| (1) | ||
float remquo ( float x, float y, int* quo ); double remquo ( double x, double y, int* quo ); |
(C++11以降) (C++23まで) |
|
| constexpr /* floating-point-type */ remquo ( /* 浮動小数点型 */ x, |
(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 > /* 共通浮動小数点型 */ |
(A) | (C++11以降) (C++23 以降 constexpr) |
std::remquo のオーバーロードを提供します。(since C++23)目次 |
[edit] パラメータ
| x, y | - | 浮動小数点または整数値 |
| quo | - | x / y の符号と下位ビットを格納するための、int へのポインタ |
[edit] 戻り値
成功した場合、x / y の除算の浮動小数点剰余を std::remainder で定義されている通りに返します。また、*quo には、x / y の符号と下位 3 ビット以上のビットを格納します(正式には、符号が x / y の符号であり、絶対値が x / y の整数商の絶対値に、n ≥ 3 である実装定義の整数 n を法として合同な値を格納します)。
y がゼロの場合、*quo に格納される値は未定義です。
領域エラーが発生した場合、実装定義の値が返される (サポートされている場合はNaN)。
アンダーフローによる範囲エラーが発生した場合、サブノーマルがサポートされていれば正しい結果が返されます。
y がゼロでも、定義域エラーが発生しない場合、ゼロが返されます。
[edit] エラー処理
エラーは 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 が返されます。
[edit] 注記
POSIX では、x が無限大であるか y がゼロである場合に定義域エラーが発生することが要求されています。
この関数は、周期が浮動小数点値として正確に表現できる周期関数を実装する際に役立ちます。非常に大きな x に対して sin(πx) を計算する場合、std::sin を直接呼び出すと大きな誤差が生じる可能性がありますが、関数引数をまず std::remquo で正規化すると、商の下位ビットを使用して周期内での結果の符号とオクターントを決定でき、剰余を使用して高精度で値を計算できます。
一部のプラットフォームでは、この操作はハードウェアでサポートされています(例:Intel CPU では、FPREM1 は完了時に商に正確に 3 ビットの精度を残します)。
追加のオーバーロードは (A) とまったく同じように提供される必要はない。それらは、最初の引数 num1 と2番目の引数 num2 に対して以下を保証するのに十分である必要がある。
|
(C++23まで) |
|
num1 と num2 が算術型である場合、std::remquo(num1, num2, quo) は std::remquo(static_cast</*共通浮動小数点型*/>(num1), そのような最高のランクとサブランクセを持つ浮動小数点型が存在しない場合、オーバーロード解決は提供されたオーバーロードから使用可能な候補を導出しません。 |
(C++23から) |
[edit] 例
#include <cfenv> #include <cmath> #include <iostream> #ifndef __GNUC__ #pragma STDC FENV_ACCESS ON #endif const double pi = std::acos(-1); // or std::numbers::pi since C++20 double cos_pi_x_naive(double x) { return std::cos(pi * x); } // the period is 2, values are (0;0.5) positive, (0.5;1.5) negative, (1.5,2) positive double cos_pi_x_smart(double x) { int quadrant; double rem = std::remquo(x, 1, &quadrant); quadrant = static_cast<unsigned>(quadrant) % 2; // The period is 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'; // error handling 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 raised\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
[edit] 関連項目
| (C++11) |
整数の除算における商と剰余を計算する (関数) |
| (C++11)(C++11) |
浮動小数点数の除算操作における剰余 (関数) |
| (C++11)(C++11)(C++11) |
除算操作における符号付き剰余 (関数) |
| C のドキュメント (remquo について)
| |