命名空间
变体
操作

remquo, remquof, remquol

来自 cppreference.cn
< c‎ | numeric‎ | math
 
 
 
常用数学函数
函数
基本运算
remquo
(C99)
(C99)
(C99)
(C99)(C99)(C99)(C23)
最大值/最小值运算
(C99)
(C99)
指数函数
(C23)
(C99)
(C99)
(C23)
(C23)

(C99)
(C99)(C23)
(C23)
(C23)
幂函数
(C99)
(C23)
(C23)

(C99)
(C23)
(C23)
三角函数和双曲函数
(C23)
(C23)
(C23)
(C23)
(C99)
(C99)
(C99)
最近整数浮点
(C99)(C99)(C99)
(C99)

(C99)(C99)(C99)
(C23)(C23)(C23)(C23)
浮点操作
(C99)(C99)
(C99)(C23)
(C99)
窄化操作
(C23)
(C23)
(C23)
(C23)
(C23)
(C23)
量子和量子指数
十进制重编码函数
总顺序和有效载荷函数
分类
(C99)
(C99)
(C99)
(C23)
误差函数和伽玛函数
(C99)
(C99)
(C99)
(C99)
类型
宏常量
特殊浮点值
(C99)(C23)
参数和返回值
错误处理
快速运算指示符
 
定义于头文件 <math.h>
float       remquof( float x, float y, int *quo );
(1) (since C99)
double      remquo( double x, double y, int *quo );
(2) (since C99)
long double remquol( long double x, long double y, int *quo );
(3) (since C99)
定义于头文件 <tgmath.h>
#define remquo( x, y, quo )
(4) (since C99)
1-3) 计算除法运算 x/y 的浮点余数,如同 remainder() 函数一样。此外, x/y 的符号和至少最后三位将被存储在 quo 中,足以确定结果在一个周期内的八分圆。
4) 类型泛型宏:如果任何非指针参数具有 long double 类型,则调用 remquol。否则,如果任何非指针参数具有整数类型或 double 类型,则调用 remquo。否则,调用 remquof

目录

[编辑] 参数

x, y - 浮点值
quo - 指向整数值的指针,用于存储 x/y 的符号和一些位

[编辑] 返回值

如果成功,则返回除法 x/y 的浮点余数,如 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) 时,直接调用 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);
}
 
// 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)
{
    const double pi = acos(-1);
    int extremum;
    double rem = remquo(x, 1, &extremum);
    extremum = (unsigned)extremum % 2; // keep 1 bit to determine nearest extremum
    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));
 
    // error handling
    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)
计算浮点除法运算的余数
(函数) [编辑]
计算浮点除法运算的带符号余数
(函数) [编辑]
C++ 文档 for remquo