fenv.h 文件定义了数据类型 fenv_t,它表示整个浮点环境,包括异常标志、舍入控制模式、异常处理模式和(在 SPARC 上的)非标准模式。在以下说明中,envp 参数必须是指向类型为 fenv_t 的对象的指针。
C99 定义 4 个函数以处理浮点环境。libm 提供的一个附加函数在多线程程序中非常有用。下表概要介绍了这些函数:
|
fegetenv 和 fesetenv 函数分别用来保存和恢复浮点环境。fesetenv 的参数可以是指向以前通过调用 fegetenv 或 feholdexcept 保存的环境的指针,或者在 fenv.h 中定义的常量 FE_DFL_ENV。后者表示缺省环境,即清除所有异常标志、舍入到最接近的值以及在基于 x86 的系统上舍入到扩展双精度、不间断的异常处理模式(即禁用陷阱)以及禁用非标准的模式。
feholdexcept 函数会保存当前的环境,然后清除所有异常标志并为所有异常建立不间断的异常处理模式。feupdateenv 函数恢复保存的环境(可通过调用 fegetenv 或 feholdexcept 或常量 FE_DFL_ENV),然后引发在先前环境中设置其标志的异常。如果恢复的环境为其中的任何异常启用了陷阱,则会发生陷阱;否则,设置这些标志。可结合使用这两个函数,使子例程调用相对于异常为原子操作,如以下代码样例所示:
#include <fenv.h> void myfunc(...) { fenv_t env; /* save the environment, clear flags, and disable traps */ feholdexcept(&env); /* do a computation that may incur exceptions */ ... /* check for spurious exceptions */ if (fetestexcept(...)) { /* handle them appropriately and clear their flags */ ... feclearexcept(...); } /* restore the environment and raise relevant exceptions */ feupdateenv(&env); }
fex_merge_flags 函数对当前环境和保存环境中的异常标志执行逻辑 OR 运算,而不调用任何陷阱。可以在多线程程序中使用此函数,在父线程中保存有关子线程中的计算引发的标志的信息。有关显示 fex_merge_flags 用法的示例,请参见Appendix A, 示例。