Name | Description | Notes | Source | Availability | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|
EDOM |
Domain-error indicator | M | <errno.h> |
C89 | C90 | C95 | C99 | C11 | |||
ERANGE |
Range-error indicator | M | <errno.h> |
C89 | C90 | C95 | C99 | C11 | |||
FE_ |
All floating-point exceptions | M | <fenv.h> |
C99 | C11 | ||||||
FE_ |
Floating-point exception: division by zero | ? | M | <fenv.h> |
C99 | C11 | |||||
FE_ |
Floating-point exception: inexact computation | ? | M | <fenv.h> |
C99 | C11 | |||||
FE_ |
Floating-point exception: invalid representation | ? | M | <fenv.h> |
C99 | C11 | |||||
FE_ |
Floating-point exception: overflow | ? | M | <fenv.h> |
C99 | C11 | |||||
FE_ |
Floating-point exception: underflow | ? | M | <fenv.h> |
C99 | C11 | |||||
feclearexcept() |
Clear floating-point exceptions | (·) | <fenv.h> |
C99 | C11 | ||||||
fegetexceptflag() |
Get floating-point exception flags | (·) | <fenv.h> |
C99 | C11 | ||||||
feraiseexcept() |
Raise floating-point exceptions | (·) | <fenv.h> |
C99 | C11 | ||||||
fesetexceptflag() |
Set floating-point exception flags | (·) | <fenv.h> |
C99 | C11 | ||||||
fetestexcept() |
Test floating-point exceptions | (·) | <fenv.h> |
C99 | C11 | ||||||
fexcept_t |
Floating-point exception status | T | <fenv.h> |
C99 | C11 | ||||||
HUGE_ |
Indication of large magnitude | M | <math.h> |
C89 | C90 | C95 | C99 | C11 | |||
HUGE_ |
Indication of large magnitude | M | <math.h> |
C99 | C11 | ||||||
HUGE_ |
Indication of large magnitude | M | <math.h> |
C99 | C11 | ||||||
MATH_ |
Indicator of raising of exception on mathematical error | M | <math.h> |
C11 | |||||||
MATH_ |
Indicator of use of errno on mathematical
error |
M | <math.h> |
C11 | |||||||
math_ |
Container for
MATH_ and
MATH_ |
M | <math.h> |
C11 | |||||||
SIGFPE |
Floating-point exception | M | <signal.h> |
C89 | C90 | C95 | C99 | C11 |
Floating-point computations can error or
produce inaccurate results under many circumstances. C
programs can detect when these have happened by observing
errno
and checking for
floating-point exceptions.
Exception types are identified by macros defined in
<fenv.h>
beginning with
FE_
and an upper-case letter. (Note
that there are other macros with the same pattern that do not
identify exceptions, such as FE_
.) Each one is a distinct
integer expression, and they can be OR-ed together to
represent sets of exception types, e.g.,
FE_
.
FE_
represents the set of all exception types. The following
exception types are specified:
FE_
DIVBYZERO FE_
INEXACT FE_
INVALID FE_
OVERFLOW FE_
UNDERFLOW
Macros with names matching ^FE_[A-Z]
might be added to <fenv.h>
.
Raising a floating-point exception can result
in a signal of type SIGFPE
being raised. Returning from the signal handler has undefined
behaviour, so all you can portably do in there is perhaps
print a message an abort. [Not even sure
whether printing is safe.] However, no function in
<math.h>
may raise SIGFPE
,
though it can quietly raise
FE_
,
FE_
or FE_
according to the result. feholdexcept
can also be
used to disable raising of SIGFPE
until a subsequent call to feupdateenv
.
The floating-point environment includes a
set of status flags, which remember which exceptions have
been recently raised in the current thread. An object of type
fexcept_t
can be used to store a copy these flags:
#include<fenv.h>
#pragma STDC FENV_ACCESS ON int fegetexceptflag(fexcept_t *flp, int excepts); int fesetexceptflag(const fexcept_t *flp, int excepts);
These functions allow a program to save (fegetexceptflag
)
and restore (fesetexceptflag
)
the floating-point status flags as a single operation.
Restoring the state does not cause the exceptions to be
raised. The argument excepts
acts as a
filter, indicating which flags to save or restore. State is
saved to or restored from *flp
. The
functions return non-zero on failure.
There is no direct portable way to set an fexcept_t
to a specific value; the state passed to fesetexceptflag
must come from a previous call to fegetexceptflag
,
and the filter controlling fesetexceptflag
must be a subset of the filter controlling fegetexceptflag
.
However, it should be possible by enabling non-stop mode for
all exceptions, raising the ones you want, recording the new
state, restoring all FP state, and then optionally setting
the state from the stored flags:
#pragma STDC FENV_ACCESS ON fenv_t env; fexcept_t exes; feholdexcept(&env); feraiseexcept(FE_INVALID ); fegetexceptflag(&exes, FE_INVALID ); feupdateenv(&env); fesetexceptflag(&exes, FE_INVALID );
#include<fenv.h>
#pragma STDC FENV_ACCESS ON int feclearexcept(int excepts); int fetestexcept(int excepts); int feraiseexcept(int excepts);
These functions directly interact with the status flags
identified by excepts
. feclearexcept
attempts to clear the specified status flags, while
feraiseexcept
attempts to raise the specified exceptions. The functions
return zero on total success. fetestexcept
tests the specified exceptions, and returns the OR of the
flags that are set.
A domain error occurs when a mathematical
function is computed, but the input is outside the function's
domain, i.e., the set
of arguments for which the function is defined. For example,
the domain of the arc sine does not include real numbers
greater than +1 or less than −1. A domain error is signalled
by the
FE_
exception, and by errno
containing EDOM
.
A pole error occurs when the input is correctly
in the domain, but the result is some form of infinity. For
example, the logarithm of zero is negative infinity. A pole
error is signalled by
FE_
.
A range error is an overflow or underflow.
-
An overflow occurs when the input is correctly in the domain, and the result is not an infinity, but it is too large to be represented. The actual value yielded by the computation will be one of ±
HUGE_
, ±VAL HUGE_
and ±VALF HUGE_
, as appropriate to the type of the computation and the sign of the true result. An overflow exception is signalled byVALL FE_
. If this macro is not defined, overflows are not signalled by exceptions.OVERFLOW [: If infinity is not supported, isHUGE_
used instead, and is it considered an overflow?]VAL -
An underflow occurs when the input is correctly in the domain, and the result is not zero, but it is too small to be represented. The actual value yielded by the computation will be a small non-zero amount with the correct sign. An overflow exception is signalled by
FE_
. If this macro is not defined, underflows are not signalled by exceptions.UNDERFLOW
Overflows and pole errors are additionally signalled by
errno
containing ERANGE
.
Underflows might also be signalled this way.
FE_
is an exception that may be
raised by functions in <math.h>
when the true
mathematical result cannot be represented exactly in the
result type, or when a floating-point value is converted to
an integer.
Functions such as nearbyint
exist specifically to avoid
this exception. Other rounding functions are permitted to raise it when
the input and output differ.
math_
is an expression of type
int
. If the
expression
math_
is non-zero, then:
FE_
is raised when a domain error occurs,INVALID FE_
is raised when a pole error occurs, andDIVBYZERO FE_
is raised when an overflow occurs,OVERFLOW
If the expression is zero, then:
FE_
is not raised when an underflow occurs.UNDERFLOW
If the expression
math_
is non-zero, then:
errno
is set toEDOM
when a domain error occurs, anderrno
is set toERANGE
when a pole error or an overflow occurs.
If the expression is zero, then:
errno
is not set when an underflow occurs.