Oracle® Solaris Studio 12.4: Numerical Computation Guide

Exit Print View

Updated: January 2015
 
 

3.5.3 Environment Functions

The fenv.h file defines the data type fenv_t, which represents the entire floating-point environment including exception flags, rounding control modes, exception handling modes, and, on SPARC, nonstandard mode. In the descriptions that follow, the envp parameter must be a pointer to an object of type fenv_t.

C99 defines four functions to manipulate the floating-point environment. libm provides an additional function that can be useful in multi-threaded programs. These functions are summarized in the following table:

Table 3-16  libm Floating-Point Environment Functions
Function
Action
fegetenv(envp)
save environment in *envp
fesetenv(envp)
restore environment from *envp
feholdexcept(envp)
save environment in *envp and establish nonstop mode
feupdateenv(envp)
restore environment from *envp and raise exceptions
fex_merge_flags(envp)
“or” exception flags from *envp

The fegetenv and fesetenv functions respectively save and restore the floating-point environment. The argument to fesetenv can be either a pointer to an environment previously saved by a call to fegetenv or feholdexcept or the constant FE_DFL_ENV defined in fenv.h. The latter represents the default environment with all exception flags clear, rounding to nearest and to extended double precision on x86-based systems, nonstop exception handling mode (i.e., traps disabled), and nonstandard mode disabled.

The feholdexcept function saves the current environment and then clears all exception flags and establishes nonstop exception handling mode for all exceptions. The feupdateenv function restores a saved environment (which might be one saved by a call to fegetenv or feholdexcept or the constant FE_DFL_ENV), then raises those exceptions whose flags were set in the previous environment. If the restored environment has traps enabled for any of those exceptions, a trap occurs; otherwise the flags are set. These two functions can be used in conjunction to make a subroutine call appear to be atomic with regard to exceptions, as the following code sample shows:

#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);
}

The fex_merge_flags function performs a logical OR of the exception flags from the saved environment into the current environment without provoking any traps. This function can be used in a multi-threaded program to preserve information in the parent thread about flags that were raised by a computation in a child thread. See Appendix A, Examples for an example showing the use of fex_merge_flags.