fenv.h provides access to the floating-point environment: exceptional conditions raised by floating-point operations and interfaces for inspecting or clearing them. Supported conditions commonly include division by zero, inexact results, invalid operations, overflow, and underflow. Availability and behavior depend on the platform, so numerical code should avoid operations that are not mathematically defined for its underlying type. section 15.1.1
Inspecting floating-point exceptions
Clear the environment before an operation, perform the operation, then call fetestexcept to query FE_ALL_EXCEPT. The returned flags can be decoded by testing individual FE_* values; call feclearexcept again before the next independent measurement. section 15.1.1
int excepts[] = {
#ifdef FE_DIVBYZERO
FE_DIVBYZERO,
#endif
#ifdef FE_INEXACT
FE_INEXACT,
#endif
#ifdef FE_INVALID
FE_INVALID,
#endif
#ifdef FE_OVERFLOW
FE_OVERFLOW,
#endif
#ifdef FE_UNDERFLOW
FE_UNDERFLOW,
#endif
};
Builds a portable list of available FE_* exception flags by conditionally including macros supported by the implementation. section 15.1.1
void printexcept(void) {
char const* name[] = {
#ifdef FE_DIVBYZERO
"divbyzero",
#endif
#ifdef FE_INEXACT
"inexact",
#endif
#ifdef FE_INVALID
"invalid",
#endif
#ifdef FE_OVERFLOW
"overflow",
#endif
#ifdef FE_UNDERFLOW
"underflow",
#endif
};
int except = fetestexcept(FE_ALL_EXCEPT);
if (except) {
printf("[");
for (unsigned j = 0; except; except &= ~excepts[j], ++j)
if (excepts[j] & except)
printf("%s ", name[j]);
printf("]");
}
}
int main (int argc, char* argv[static argc+1]) {
printf("division by zero is %sequal to INFINITY\n", has_inf ? "" : "un");
for (unsigned i = 1; i < argc; i++) {
feclearexcept(FE_ALL_EXCEPT);
double x = strtod(argv[i], nullptr);
printf("%g ", x);
printexcept();
feclearexcept(FE_ALL_EXCEPT);
printf(": %g ", 1.0/x);
printexcept();
puts("");
}
}
Demonstrates clearing exceptions, converting command-line input, testing flags, and reporting conditions raised by division. section 15.1.1
