命名空间
变体
操作

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

来自 cppreference.cn
< cpp‎ | numeric‎ | math
 
 
 
常用数学函数
函数
基本运算
(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 起)
(constexpr 自 C++23 起)
long double remquol( long double x, long double y, int* quo );
(3) (自 C++11 起)
(constexpr 自 C++23 起)
定义于头文件 <cmath>
template< class Arithmetic1, class Arithmetic2 >

/* 共同浮点类型 */

    remquo( Arithmetic1 x, Arithmetic2 y, int* quo );
(A) (自 C++11 起)
(constexpr 自 C++23 起)
1-3) 就像 std::remainder() 函数那样,计算除法运算 x / y 的浮点余数。此外,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 的符号,并且其大小与 x / y 的整数商的大小模 2n
同余,其中 n 是大于或等于 3 的实现定义的整数)。

如果 y 为零,则存储在 *quo 中的值是未指定的。

如果发生域错误,则返回实现定义的值(如果支持,则为 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</*共同浮点类型*/>(num1),
            static_cast</*共同浮点类型*/>(num2), quo)
相同的效果,其中 /*共同浮点类型*/ 是浮点类型,在 浮点转换等级 中具有最高等级,并在 浮点转换子等级 中具有最高等级,介于 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