MATH_ERRNO, MATH_ERREXCEPT, math_errhandling

来自cppreference.com
< c‎ | numeric‎ | math


 
 
 
常用数学函数
类型
(C99)(C99)    

(C99)(C99)    

函数
基本运算
(C99)
(C99)
(C99)
(C99)(C99)(C99)(C23)
最大/最小运算
(C99)
(C23)    
指数函数
(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)
(C99)
(C99)(C99)(C99)
(C23)(C23)(C23)(C23)
浮点操作函数
(C99)(C99)
(C99)(C23)
(C99)
窄化运算
(C23)
(C23)
(C23)
(C23)
(C23)
(C23)
量与量指数函数
十进制重编码函数
全序与载荷函数
分类
(C99)
(C99)
(C99)
(C23)
宏常量
特殊浮点值
(C99)(C23)
参数与返回值
(C99)(C99)(C99)(C99)(C99)    
错误处理
MATH_ERRNOMATH_ERRNOEXCEPT
(C99)(C99)
math_errhandling
(C99)    

 
在标头 <math.h> 定义
#define MATH_ERRNO        1
(C99 起)
#define MATH_ERREXCEPT    2
(C99 起)
#define math_errhandling  /* 由实现定义 */
(C99 起)

宏常量 math_errhandling 展开成 int 类型的表达式,要么等于 MATH_ERRNO,要么等于 MATH_ERREXCEPT,要么等于其逐位或(MATH_ERRNO | MATH_ERREXCEPT)。

math_errhandling 的值指示浮点运算符和函数所进行的错误处理:

常量 解释
MATH_ERREXCEPT 指示使用浮点异常:<fenv.h> 中至少定义了 FE_DIVBYZEROFE_INVALIDFE_OVERFLOW
MATH_ERRNO 指明浮点运算使用变量 errno 报告错误。

若实现支持 IEEE 浮点算术(IEC 60559),则要求 math_errhandling & MATH_ERREXCEPT 非零。

识别下列浮点错误条件:

条件 解释 errno 浮点异常 示例
定义域错误 实参在该运算的数学上的定义域之外(每个函数的描述列出了要求的定义域错误) EDOM FE_INVALID acos(2)
极点错误 函数的数学结果恰是无限大或未定义 ERANGE FE_DIVBYZERO log(0.0)1.0/0.0
上溢所致的值域错误 数学结果有限,但舍入后变为无限,或在向下舍入后变成最大可表示有限值 ERANGE FE_OVERFLOW pow(DBL_MAX,2)
下溢所致的值域错误 结果非零,但因为舍入变为零,或变成非正规并有精度损失 ERANGE 或不改变(实现定义) FE_UNDERFLOW 或无(实现定义) DBL_TRUE_MIN/2
结果不准确 结果必须被舍入到目标类型 不改变 FE_INEXACT或无(未指定) sqrt(2)1.0/10.0

注意

通常,FE_INEXACT 是否为数学库函数所引发是未指定的,但这可以显式指定于函数的描述(例如 rint vs nearbyint)。

C99 前,浮点异常是未指定的,要求对于任何定义于错误发生 EDOM,要求对上溢和实现定义的下溢发生 ERANGE

示例

#include <stdio.h>
#include <fenv.h>
#include <math.h>
#include <errno.h>
#pragma STDC FENV_ACCESS ON
int main(void)
{
    printf("MATH_ERRNO is %s\n", math_errhandling & MATH_ERRNO ? "set" : "not set");
    printf("MATH_ERREXCEPT is %s\n",
           math_errhandling & MATH_ERREXCEPT ? "set" : "not set");
    feclearexcept(FE_ALL_EXCEPT);
    errno = 0;
    printf("log(0) = %f\n", log(0));
    if(errno == ERANGE)
        perror("errno == ERANGE");
    if(fetestexcept(FE_DIVBYZERO))
        puts("FE_DIVBYZERO (pole error) reported");
}

可能的输出:

MATH_ERRNO is set
MATH_ERREXCEPT is set
log(0) = -inf
errno = ERANGE: Numerical result out of range
FE_DIVBYZERO (pole error) reported

引用

  • C17 标准(ISO/IEC 9899:2018):
  • 7.12/9 MATH_ERRNO, MATH_ERREXCEPT, math_errhandling (第 170 页)
  • F.10/4 MATH_ERREXCEPT, math_errhandling (第 377 页)
  • C11 标准(ISO/IEC 9899:2011):
  • 7.12/9 MATH_ERRNO, MATH_ERREXCEPT, math_errhandling (第 233 页)
  • F.10/4 MATH_ERREXCEPT, math_errhandling (第 517 页)
  • C99 标准(ISO/IEC 9899:1999):
  • 7.12/9 MATH_ERRNO, MATH_ERREXCEPT, math_errhandling (第 214 页)
  • F.9/4 MATH_ERREXCEPT, math_errhandling> (第 454 页)


参阅

浮点异常
(宏常量)
展开成 POSIX 兼容的线程局域错误编号变量
(宏变量)