Namespaces
Variants

MATH_ERRNO, MATH_ERREXCEPT, math_errhandling

From cppreference.net
< c ‎ | numeric ‎ | math
Common mathematical functions
Functions
Basic operations
(C99)
(C99)
(C99)
(C99) (C99) (C99) (C23)
Maximum/minimum operations
Exponential functions
Power functions
Trigonometric and hyperbolic functions
Nearest integer floating-point
(C99) (C99) (C99)
(C23) (C23) (C23) (C23)
Floating-point manipulation
Narrowing operations
(C23)
(C23)
(C23)
(C23)
(C23)
(C23)
Quantum and quantum exponent
Decimal re-encoding functions
Total order and payload functions
Classification
Error and gamma functions
(C99)
(C99)
(C99)
(C99)
Types
Macro constants
Special floating-point values
Arguments and return values
Error handling
MATH_ERRNO MATH_ERRNOEXCEPT
(C99) (C99)
math_errhandling
(C99)

Fast operation indicators
定义于头文件 <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 表示使用浮点异常:至少 FE_DIVBYZERO FE_INVALID FE_OVERFLOW <fenv.h> 中定义。
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 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 已设置
MATH_ERREXCEPT 已设置
log(0) = -inf
errno = ERANGE: 数值结果超出范围
FE_DIVBYZERO(极点错误)已报告

参考文献

  • 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 (p: 233)
  • F.10/4 MATH_ERREXCEPT, math_errhandling (p: 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兼容的线程局部错误编号变量的宏
(宏变量)
C++ 文档 关于 math_errhandling