fenv函数用法详解
fenv函数简介
- 头文件包含
#include <fenv.h>
- 函数定义
int feclearexcept(int excepts );
int fegetexceptflag(fexcept_t * flagp , int excepts );
int feraiseexcept(int excepts );
int fesetexceptflag(const fexcept_t * flagp , int excepts );
int fetestexcept(int excepts );
int fegetround(void);
int fesetround(int rounding_mode );
int fegetenv(fenv_t * envp );
int feholdexcept(fenv_t * envp );
int fesetenv(const fenv_t * envp );
int feupdateenv(const fenv_t * envp );
- 编译链接选项
-lm
fenv函数常见使用错误
- 链接错误
undefined reference to `fenv'
解决办法:添加链接选项
-lm
- 编译错误
warning: implicit declaration of function ‘fenv’ [-Wimplicit-function-declaration]
解决办法:包含头文件
#include <fenv.h>
fenv函数详细描述
这11个函数是在C99中定义的,描述了浮点舍入和异常(溢出、零除等)的处理。Exceptions当对有限数的运算产生无穷大作为精确答案时,就会发生divide-by-zero异常。
当结果必须表示为浮点数,但其绝对值比可表示的最大(有限)浮点数大得多时,就会发生overflow异常。
当结果必须表示为浮点数,但绝对值小于最小正的规范化浮点数时,就会发生underflow异常(如果表示为非规范化的数字,则会损失很大的精确度)。
当运算的舍入结果不等于无限精度结果时,会发生inexact异常。无论何时发生overflow或underflow都可能发生。
当某个操作没有定义良好的结果时,就会发生invalid异常,例如0/0或无穷大-无穷大或sqrt(-1)。Exception handling异常以两种方式表示:作为单个位(异常存在/不存在),这些位以某种实现定义的方式与整数中的位位置相对应,以及作为一个不透明的结构,该结构可能包含关于异常的更多信息(可能是异常发生的代码地址)。
当实现支持处理相应的异常时,定义每个宏FE_DIVBYZERO FE_INEXACT FE_INVALID FE_OVERFLOW FE_UNDERFLOW ,如果支持,则定义相应的位,以便可以调用异常处理函数,例如使用整数参数FE_OVERFLOW | FE_UNDERFLOW ,可以支持其他异常。宏 FE_ALL_EXCEPT 是与支持的异常对应的所有位的按位或。
feclearexcept ()函数清除由其参数中的位表示的受支持的异常。
fegetexceptflag ()函数在不透明对象flagp 中存储由参数excepts表示的异常标志的状态表示
feraiseexcept ()函数引发由excepts 中的位表示的受支持的异常
fesetexceptflag ()函数将excepts表示的异常的完整状态设置为值flagp ,该值必须是通过先前调用fegetexceptflag ()获得的,该调用的最后一个参数包含excepts 中的所有位
fetestexcept ()函数返回一个字,其中设置了参数excepts中设置的位,并且当前为其设置了相应的异常。Rounding mode舍入模式决定了当浮点运算的结果不能在显式中准确表示时,如何处理浮点运算的结果。可以提供各种舍入模式:舍入到最接近(默认)、向上舍入(向正无穷大)、向下舍入(向负无穷大)和向零舍入。
当实现支持获取和设置相应的舍入方向时,定义每个宏FE_TONEAREST ,FE_UPWARD ,FE_DOWNWARD 和FE_TOWARDZERO。
fegetround ()函数返回与当前舍入模式相对应的宏。
fesetround ()函数设置其参数指定的舍入模式,并在成功时返回零。
C99和POSIX.1-2008指定了一个标识符,FLT_ROUNDS 在
- 舍入模式无法确定。
- 四舍五入是向0。
- 四舍五入是向最近的数字。
- 四舍五入是朝向正无穷大。
- 四舍五入是向负无穷大。
其他值表示依赖于机器的非标准舍入模式。
FLT_ROUNDS的值应该反映fesetround ()设置的当前舍入模式(但请参见bug)。Floating-point environment整个浮点环境,包括控制模式和状态标志,可以作为一个不透明的对象来处理,类型为fenv_t 默认环境由 FE_DFL_ENV 表示(类型为"const fenv_t\ " )这是程序开始时的环境设置,由ISO C定义为具有从圆到最近、清除所有异常和不停止(在异常时继续)模式。
fegetenv ()函数将当前浮点环境保存在对象envp 中
feholdexcept ()函数执行相同的操作,然后清除所有异常标志,并设置一个nonstop(在异常上继续)模式(如果可用的话)。成功时返回零。
fesetenv ()函数从对象envp 恢复浮点环境。这个对象必须知道是有效的,例如,调用fegetenv ()或feholdexcept ()或等于FE_DFL_ENV 的结果。这个调用不会引发异常。
feupdateenv ()函数安装由对象envp 表示的浮点环境,但当前引发的异常未被清除。调用此函数后,引发的异常将是先前与envp 中的异常一起设置的按位或,正如以前一样,必须知道对象envp是有效的。
fenv函数返回值
这些函数在成功时返回零,在发生错误时返回非零。
fenv函数其他说明
如果可能的话,GNU C库定义宏 FE_NOMASK_ENV ,它表示一个环境,在这个环境中,引发的每个异常都会导致陷阱发生。您可以使用#ifdef 来测试这个宏,它只有在定义了 _GNU_SOURCE 的情况下才被定义。C99标准没有定义在浮点掩码中设置单个位的方法,例如,在特定标志上设置陷阱。从2.2版开始,glibc支持函数feenableexcept ()和fedisableexcept ()来设置单个浮点陷阱,并支持函数fegetexcept ()来查询状态。
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <fenv.h>
int feenableexcept(int excepts );
int fedisableexcept(int excepts );
int fegetexcept(void);
feenableexcept ()和fedisableexcept ()函数为excepts表示的每个异常启用(禁用)陷阱,并在成功时返回上一组启用的异常,否则返回-1。fegetexcept ()函数返回当前启用的所有异常集。
评论区