Include the standard header <fenv.h>
to define two types, several macros, and several functions
that test and control floating-point status, if the implementation permits.
The functionality matches IEC 60559, but it can
be applied to similar floating-point hardware.
Floating-point status
can be represented in an object of type
fexcept_t.
It forms part of the
floating-point control,
which determines the behavior of floating-point arithmetic. A copy of the
floating-point control can be represented in an object of type
fenv_t.

Another part of the floating-point control is the
rounding mode,
representable as a value of type int, which determines
how floating-point values convert to integers. The rounding modes
are:

downward, toward the nearest more negative integer

to nearest, toward the nearest integer with the closer value,
or toward the nearest even integer if two integers are equally near

By convention, a C function does not alter the floating-point control,
nor assume other than the default settings for the floating-point control,
without explicitly documenting the fact.
Any C function can change the floating-point status by
reporting one of several floating-point exceptions:

An inexact floating-point exception
can occur when a finite floating-point result cannot be exactly represented, as in
2.0 / 3.0.

An invalid floating-point exception
can occur when a floating-point operation involves an invalid combination of
operators and operands, as in 0.0 / 0.0.

An overflow floating-point exception
can occur when the magnitude of a finite floating-point result is too large to represent,
as in DBL_MAX / DBL_MIN.

An underflow floating-point exception
can occur when the magnitude of a finite floating-point result is too small to represent,
as in DBL_MIN / DBL_MAX.

A zero-divide floating-point exception
can occur when a floating-point divide has a finite dividend and a zero divisor, as in
1.0 / 0.0.

An implementation may define additional floating-point exceptions.

Reporting an exception sets a corresponding indicator in the floating-point
status. It can also raise
a floating-point exception, which can result in a hardware trap
and/or the raising of a signal.

informs the translator whether the program intends to control and
test floating-point status. If the parameter is
ON, the program may use the functions declared in this header
to control and test floating-point status.
If the parameter is OFF, the use of these functions is disallowed.
The parameter DEFAULT restores the original state,
which is implementation defined.
If the pragma occurs outside an external declaration,
it remains in effect until overridden by another such pragma. If the pragma occurs
inside an external declaration, it must precede all explicit declarations and
statements within a compound statement. It remains in effect until overridden by
another such pragma or until the end of the compound statement.
On a transition from OFF to ON,
floating-point status flags are unspecified and the floating-point
control is in its default state.

The macro expands to an integer value that, when ANDed with a value of type
fexcept_t, yields a nonzero value only
if the indicator is set for one or more floating-point exceptions.
The macro is not defined if the functions declared in this header cannot
control floating-point exceptions.

The macro expands to an integer value that, when ANDed with a value of type
fexcept_t, yields a nonzero value only
if the indicator is set for a
zero-divide floating-point exception.
The macro is not defined if the functions declared in this header cannot
control floating-point exceptions.

The macro expands to an integer value accepted as an argument to
fesetround
and returned by
fegetround
to indicate the downwardrounding mode.
The macro is not defined if the functions declared in this header cannot
control the rounding mode.

The macro expands to an integer value that, when ANDed with a value of type
fexcept_t, yields a nonzero value only
if the indicator is set for an
inexact floating-point exception.
The macro is not defined if the functions declared in this header cannot
control floating-point exceptions.

The macro expands to an integer value that, when ANDed with a value of type
fexcept_t, yields a nonzero value only
if the indicator is set for an
invalid floating-point exception.
The macro is not defined if the functions declared in this header cannot
control floating-point exceptions.

The macro expands to an integer value accepted as an argument to
fesetround
and returned by
fegetround
to indicate the to nearestrounding mode.
The macro is not defined if the functions declared in this header cannot
control the rounding mode.

The macro expands to an integer value accepted as an argument to
fesetround
and returned by
fegetround
to indicate the toward zerorounding mode.
The macro is not defined if the functions declared in this header cannot
control the rounding mode.

The macro expands to an integer value that, when ANDed with a value of type
fexcept_t, yields a nonzero value only
if the indicator is set for an
overflow floating-point exception.
The macro is not defined if the functions declared in this header cannot
control floating-point exceptions.

The macro expands to an integer value that, when ANDed with a value of type
fexcept_t, yields a nonzero value only
if the indicator is set for an
underflow floating-point exception.
The macro is not defined if the functions declared in this header cannot
control floating-point exceptions.

The macro expands to an integer value accepted as an argument to
fesetround
and returned by
fegetround
to indicate the upwardrounding mode.
The macro is not defined if the functions declared in this header cannot
control the rounding mode.

The function attempts to clear
the exceptions selected by except in the
floating-point status portion of the
floating-point control.
It returns zero only if except is zero or all the
exceptions selected by except are successfully cleared.

The function returns the current
floating-point enable mask from the
floating-point control,
or (fexcept_t)(-1) if it cannot be determined.
For an exception selected by except (such as FE_OVERFLOW),
an operation that raises
the exception results in a hardware trap and/or the raising of a
signal
only if fegettrapenable() & except is nonzero.
At program startup,
fegettrapenable() returns zero.

The function attempts to store in *pflag a representation of
the exceptions selected by except from the
floating-point status portion of the
floating-point control.
It returns zero only if except is zero or all the
exceptions selected by except are successfully stored.

The function stores the settings in the
floating-point control
at *penv. It also clears all exceptions in the
floating-point status portion of the
floating-point control and endeavors to establish settings that will not
raise any exceptions. (The
effect is equivalent to calling
fegetenv(penv) followed by
feclearexcept(FE_ALL_EXCEPT) and
fesettrapenable(0).) The function returns
zero only if it succeeds in establishing such settings.

You can use this function in conjunction with
feupdateenv
to defer the raising of exceptions until spurious ones are cleared, as in:

The function attempts to set
the exceptions selected by except in the
floating-point status portion of the
floating-point control to the
values of the corresponding bits selected by
except & *pflag.
It returns zero only if except is zero or all the
exceptions selected by except & *pflag are successfully set.

The value stored in *pflag must be determined by an earlier
call to fegetexceptflag,
without an intervening call to
fesettrapenable.
Otherwise, if fegettrapenable() &
except & *pflag is nonzero,
it is unspecified whether the function evaluation
results in a hardware trap and/or the raising of a
signal.

The function sets the current
rounding mode from mode in the
floating-point control.
An invalid value of mode leaves the rounding mode
unchanged. The function returns zero only if the rounding mode is
successfully set to mode.

The function sets the current
floating-point enable mask from
enables. An invalid value of enables leaves the
floating-point enable mask unchanged. The function returns zero only if the
floating-point enable mask is successfully set to enables.

If fetestexcept(enables) is nonzero,
it is unspecified whether fesettrapenable(enables)
results in a hardware trap and/or the raising of a
signal.

Thus, it restores the settings in the
floating-point control from
*penv, after first saving the exceptions selected by the current
floating-point status
stored in the floating-point control. The function then
raises the saved
exceptions. It returns zero only if the settings
are successfully restored.

The restored settings must be determined by
FE_DFL_ENV
or by an earlier call to
fegetenv or
feholdexcept.
Otherwise, it is unspecified whether the call fesetenv(penv)
results in a hardware trap and/or the raising of a
signal.