Saves the current floating-point environment and switches to nonstop mode #include <fenv.h> int feholdexcept ( fenv_t *envp ); Like fegetenv( ), the feholdexcept( ) function saves the current floating-point environment in the object pointed to by the pointer argument. However, feholdexcept( ) also clears the floating-point status flags and switches the floating-point environment to a nonstop mode, meaning that after any floating-point exception, normal execution continues uninterrupted by signals or traps. The function returns 0 if it succeeds in switching to nonstop floating-point processing; otherwise, the return value is nonzero. Example/* * Compute the hypoteneuse of a right triangle, avoiding intermediate * overflow or underflow. * * (This example ignores the case of one argument having great magnitude * and the other small, causing both overflow and underflow!) */ double hypoteneuse(double sidea, double sideb) { #pragma STDC FENV_ACCESS ON double sum, scale, ascaled, bscaled, invscale; fenv_t fpenv; int fpeflags; if ( signbit( sidea ) ) sidea = fabs( sidea ); if ( signbit( sideb ) ) sideb = fabs( sideb ); feholdexcept(&fpenv); // Save previous environment, clear exceptions, // switch to nonstop processing. invscale = 1.0; sum = sidea * sidea + sideb * sideb; // First try whether a^2 + b^2 // causes any exceptions. fpeflags = fetestexcept(FE_UNDERFLOW | FE_OVERFLOW); // Did it? if ( fpeflags & FE_OVERFLOW && sidea > 1.0 && sideb > 1.0 ) { /* a^2 + b^2 caused an overflow. Scale the triangle down. */ feclearexcept(FE_OVERFLOW); scale = scalbn(1.0, (DBL_MIN_EXP /2 )); invscale = 1.0 / scale; ascaled = scale * sidea; bscaled = scale * sideb; sum = ascaled * ascaled + bscaled * bscaled; } else if (fpeflags & FE_UNDERFLOW && sidea < 1.0 && sideb < 1.0 ) { /* a^2 + b^2 caused an underflow. Scale the triangle up. */ feclearexcept(FE_UNDERFLOW); scale = scalbn(1.0, (DBL_MAX_EXP /2 )); invscale = 1.0 / scale; ascaled = scale * sidea; bscaled = scale * sideb; sum = ascaled * ascaled + bscaled * bscaled; } feupdateenv(&env); // restore the caller's environment, and // raise any new exceptions /* c = (1/scale) * sqrt((a * scale)^2 + (b * scale)^2): */ return invscale * sqrt(sum); } See Alsofegetenv( ), fesetenv( ), feupdateenv( ), feclearexcept( ), feraisexcept( ), fegetexceptflag( ), fesetexceptflag( ), fetestexcept( ) |