remquo, remquof, remquol

来自cppreference.com
< c‎ | numeric‎ | math
 
 
 
常用数学函数
函数
基本运算
remquo
(C99)
(C99)
(C99)
(C99)
(C99)
(C99)
(C99)
(C99)
指数函数
(C99)
(C99)
(C99)
(C99)
幂函数
(C99)
(C99)
三角及双曲函数
(C99)
(C99)
(C99)
误差及伽马函数
(C99)
(C99)
(C99)
(C99)
临近整数的浮点运算
(C99)
(C99)
(C99)
(C99)
(C99)
(C99)
(C99)
浮点数操作函数
(C99)
(C99)
(C99)
(C99)
分类
(C99)
(C99)
(C99)
宏常量
 
定义于头文件 <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的至少最后三位和符号存储于quo,以有效决定结果在周期中的八分位。
4) 通用类型宏:若任何非指针参数拥有long double类型,则调用remquol。否则若任何非指针参数拥有整数类型或double类型,则调用remquo。否则,调用remquof

目录

[编辑] 参数

x, y - 浮点值
quo - 指向要存储x/y符号及其一些位的整数的指针

[编辑] 返回值

若成功,则返回按remainder中定义的x/y浮点余数,并将x/y的符号和至少最低三位存储于*quo(正式地,被存储值的符号为x/y的符号,而其绝对值同余modulo 2n
x/y的商的整数部分,其中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。

[编辑] 注意

POSIX要求x为无穷大或y为零则发生定义域错误。

此函数在实现周期可准确表示成浮点值的周期函数时有用:对非常大范围的x计算sin(πx)时,直接调用sin可能导致巨大错误,但若函数的首个参数以remquo减小,则商的低位可用于确定符号和结果在周期中的八分位置,而余数可用于以高精度计算结果的值。

一些平台上硬件支持此操作(而且,例如在Intel CPU上,FPREM1准确地留下商的3位精度)。

[编辑] 示例

#include <stdio.h>
#include <math.h>
#include <fenv.h>
 
#pragma STDC FENV_ACCESS ON
double cos_pi_x_naive(double x)
{
    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)
{
    int quadrant;
    double rem = remquo(x, 1, &quadrant);
    quadrant = (unsigned)quadrant % 4; // 保留2位移确定象限
 
    double pi = acos(-1);
    switch(quadrant) {
        case 0: return cos(pi * rem);
        case 1: return -cos(pi * rem);
        case 2: return -cos(pi * rem);
        case 3: return 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

[编辑] 参考

  • C11 standard (ISO/IEC 9899:2011):
  • 7.12.10.3 The remquo functions (p: 255)
  • 7.25 Type-generic math <tgmath.h> (p: 373-375)
  • F.10.7.3 The remquo functions (p: 529)
  • C99 standard (ISO/IEC 9899:1999):
  • 7.12.10.3 The remquo functions (p: 236)
  • 7.22 Type-generic math <tgmath.h> (p: 335-337)
  • F.9.7.3 The remquo functions (p: 465)

[编辑] 参阅

计算整数除法的商和余数
(函数) [编辑]

(C99)
(C99)
计算浮点除法运算的余数
(函数) [编辑]
计算浮点除法运算的带符号余数
(函数) [编辑]
remquoC++ 文档