The floating-point environment is the implementation state that describes exceptional floating-point conditions and helps determine whether particular operations fail. The <fenv.h> header supplies exception macros, while fetestexcept and feclearexcept query and manage recorded conditions. section 15.1.1
Important portability rules:
- Treat exception macros as bitsets; combine them with bitwise OR to represent several conditions. section 15.1.1
- Test feature availability before relying on infinity or a particular exception condition, because supported behavior varies by platform. section 15.1.1
- Clear recorded conditions before an operation, then test them afterward to distinguish exceptions produced by that operation. section 15.1.1
bool const has_inf = #ifdef INFINITY (1.0/0.0 == INFINITY) #else false #endif ;
Checks whether the implementation provides infinity and whether division by zero produces INFINITY. 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 exception conditions by including only 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("");
}
}
Clears and reports floating-point exceptions around parsed values and reciprocal calculations. section 15.1.1
