Oracle® Solaris Studio 12.4:数值计算指南

退出打印视图

更新时间: 2015 年 1 月
 
 

3.5.3 环境函数

fenv.h 文件定义了数据类型 fenv_t,它表示整个浮点环境,包括异常标志、舍入控制模式、异常处理模式和(在 SPARC 上的)非标准模式。在以下说明中,envp 参数必须是指向类型为 fenv_t 的对象的指针。

C99 定义 4 个函数以处理浮点环境。libm 提供的一个附加函数在多线程程序中非常有用。下表概要介绍了这些函数:

表 3-16  libm 浮点环境函数
函数
操作
fegetenv(envp)
将环境保存在 *envp
fesetenv(envp)
*envp 中恢复环境
feholdexcept(envp)
将环境保存在 *envp 中,并建立不间断的模式
feupdateenv(envp)
*envp 中恢复环境并引发异常
fex_merge_flags(envp)
*envp 中的“或”异常标志

fegetenvfesetenv 函数分别用来保存和恢复浮点环境。fesetenv 的参数可以是指向以前通过调用 fegetenvfeholdexcept 保存的环境的指针,或者在 fenv.h 中定义的常量 FE_DFL_ENV。后者表示缺省环境,即清除所有异常标志、舍入到最接近的值以及在基于 x86 的系统上舍入到扩展双精度、不间断的异常处理模式(即禁用陷阱)以及禁用非标准的模式。

feholdexcept 函数会保存当前的环境,然后清除所有异常标志并为所有异常建立不间断的异常处理模式。feupdateenv 函数恢复保存的环境(可通过调用 fegetenvfeholdexcept 或常量 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, 示例