名稱空間
變體
操作

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

來自 cppreference.com
< cpp‎ | 數值‎ | 數學
 
 
 
常用數學函式
函式
基本操作
(C++11)  
remquo
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)(C++11)(C++11)
指數函式
(C++11)
(C++11)

(C++11)
(C++11)
冪函式
(C++11)
(C++11)
三角
雙曲函式
(C++11)
(C++11)
(C++11)

誤差函式和伽馬函式
(C++11)
(C++11)
(C++11)
(C++11)
取整浮點運算
(C++11)(C++11)(C++11)
(C++11)
(C++11)
(C++11)(C++11)(C++11)
浮點操縱函式
(C++11)(C++11)
(C++11)
(C++11)
(C++11)(C++11)
(C++11)
分類和比較
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
型別
(C++11)
(C++11)
(C++11)
宏常量
分類
(C++11)(C++11)(C++11)(C++11)(C++11)


 
定義於標頭檔案 <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 /* 浮點型別 */

            remquo ( /* 浮點型別 */ x,

                     /* 浮點型別 */ 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 的符號以及至少最後三位將儲存在 quo 中,足以確定結果在一個週期內的象限。 庫為所有 cv-不限定浮點型別提供了 std::remquo 的過載,作為引數 xy 的型別。(C++23 起)
A) 為所有其他算術型別組合提供了附加過載。

目錄

[編輯] 引數

x, y - 浮點數或整數值
quo - 指向 int 的指標,用於儲存 x / y 的符號和一些位

[編輯] 返回值

如果成功,返回除法 x / y 的浮點餘數,其定義與 std::remainder 相同,並在 *quo 中儲存 x / y 的符號和至少三個最低有效位(形式上,儲存一個值,其符號為 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
  • 如果 xy 為 NaN,則返回 NaN。

[編輯] 注意

POSIX 要求 如果 x 是無窮大或 y 為零,則會發生域錯誤。

此函式在實現週期正好可表示為浮點值的週期函式時很有用:當計算非常大的 xsin(πx) 時,直接呼叫 std::sin 可能會導致很大的誤差,但如果函式引數首先用 std::remquo 約化,則商的低位可用於確定結果在週期內的符號和象限,而餘數可用於高精度計算值。

在某些平臺上,此操作由硬體支援(例如,在 Intel CPU 上,FPREM1 完成時在商中留下精確的 3 位精度)。

附加的過載不要求完全按照 (A) 提供。它們只需足以確保對於它們的第一引數 num1 和第二引數 num2

  • 如果 num1num2 的型別為 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)
    相同。
  • 否則,如果 num1num2 的型別為 float,則 std::remquo(num1, num2, quo) 的效果與 std::remquo(static_cast<float>(num1),
                static_cast<float>(num2), quo)
    相同。
(直至 C++23)

如果 num1num2 具有算術型別,則 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*/ 是在 num1num2 的型別之間,具有最高浮點轉換等級和最高浮點轉換次等級的浮點型別,整數型別的引數被視為具有與 double 相同的浮點轉換等級。

如果不存在具有最高等級和次等級的浮點型別,則過載決議不會從提供的過載中產生可用的候選函式。

(C++23 起)

[編輯] 示例

#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

[編輯] 參閱

計算整數除法的商和餘數
(函式) [編輯]
(C++11)(C++11)
浮點除法運算的餘數
(函式) [編輯]
(C++11)(C++11)(C++11)
除法運算的帶符號餘數
(函式) [編輯]
C 文件 關於 remquo