©
本文档使用
php.cn手册 发布
在头文件<math.h>中定义 | ||
---|---|---|
#define MATH_ERRNO 1 | (since C99) | |
#define MATH_ERREXCEPT 2 | (since C99) | |
#define math_errhandling /*implementation defined*/ | (since C99) |
宏常量math_errhandling
扩展为int
等于MATH_ERRNO
或等于MATH_ERREXCEPT
或等于它们的OR(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
则要求为非零。
以下浮点错误条件被识别:
条件 | 说明 | 错误号 | 浮点异常 | 例 |
---|---|---|---|---|
域错误 | 参数超出了操作数学定义的范围(每个函数的描述都列出了所需的域错误) | 益登 | FE_INVALID | ACOS(2) |
极点错误 | 该函数的数学结果恰好是无限的或未定义的 | 呻吟 | FE_DIVBYZERO | 日志(0.0),1.0 / 0.0 |
由于溢出导致范围错误 | 数学结果是有限的,但在舍入后变为无限,或者在舍入后成为最大的可表示的有限值 | 呻吟 | FE_OVERFLOW | POW(DBL_MAX,2) |
由于下溢导致的范围错误 | 结果非零,但在舍入后变为零,或者由于精度损失而变为低于正常值 | ERANGE或未更改(实施定义) | FE_UNDERFLOW或者什么都没有(实现定义) | DBL_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 setMATH_ERREXCEPT is setlog(0) = -inf errno = ERANGE: Numerical result out of rangeFE_DIVBYZERO (pole error) reported
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(p:214)
F.9 / 4 MATH_ERREXCEPT,math_errhandling>(p:454)