NAME
fex_set_handling, fex_get_handling, fex_getexcepthandler,
fex_setexcepthandler - control floating point exception han-
dling modes
SYNOPSIS
cc [ flag ... ] file ... -R/opt/SUNWspro/lib
-L/opt/SUNWspro/lib -lm9x [ library ... ]
#include <fenv.h>
int fex_set_handling(int ex, int mode, void (*handler)());
int fex_get_handling(int ex);
void fex_getexcepthandler(fex_handler_t *buf, int ex);
void fex_setexcepthandler(const fex_handler_t *buf, int ex);
DESCRIPTION
These functions provide control of floating point exception
handling modes. For each function, the ex argument speci-
fies one or more exceptions indicated by a bitwise "or" of
any of the following values (defined in <fenv.h>):
FEX_INEXACT
FEX_UNDERFLOW
FEX_OVERFLOW
FEX_DIVBYZERO division by zero
FEX_INV_ZDZ 0/0 invalid operation
FEX_INV_IDI infinity/infinity invalid operation
FEX_INV_ISI infinity-infinity invalid operation
FEX_INV_ZMI 0*infinity invalid operation
FEX_INV_SQRT square root of negative operand
FEX_INV_SNAN signaling NaN
FEX_INV_INT invalid integer conversion
FEX_INV_CMP invalid comparison
For convenience, the following combinations of values are
also defined:
FEX_NONE no exceptions
FEX_INVALID all invalid operation exceptions
FEX_COMMON overflow, division by zero, and
invalid operation
FEX_ALL all exceptions
fex_set_handling(ex, mode, handler) establishes the speci-
fied mode for handling the floating point exceptions identi-
fied by ex. The selected mode determines the action to be
taken when one of the indicated exceptions occurs. It must
be one of the following values:
FEX_NOHANDLER Trap but do not otherwise handle
the exception, evoking instead
whatever ambient behavior would
normally be in effect. (This is
the default behavior when the
exception's trap is enabled. The
handler parameter is ignored.)
FEX_NONSTOP Provide the IEEE 754 default result
for the operation that caused the
exception, set the exception's
flag, and continue execution.
(This is the default behavior when
the exception's trap is disabled.
The handler parameter is ignored.)
FEX_ABORT Call abort(3C). (The handler
parameter is ignored.)
FEX_SIGNAL Invoke the function *handler with
the parameters normally supplied to
a signal handler installed via
sigfpe(3).
FEX_CUSTOM Invoke the function *handler as
described in the next paragraph.
In FEX_CUSTOM mode, when a floating point exception occurs,
the handler function is invoked as though its prototype
were:
#include <fenv.h>
void handler(int ex, fex_info_t *info);
On entry, ex is the value (of the first twelve listed above)
corresponding to the exception that occurred, info->op indi-
cates the operation that caused the exception, info->op1 and
info->op2 contain the values of the operands, info->res con-
tains the default untrapped result value, and info->flags
reflects the exception flags that the operation would have
set had it not been trapped. If the handler returns, the
value contained in info->res on exit is substituted for the
result of the operation, the flags indicated by info->flags
are set, and execution resumes at the point where the excep-
tion occurred. The handler may modify info->res and info-
>flags to supply any desired result value and flags. Alter-
natively, if the exception is underflow or overflow, the
hander may set
info->res.type = fex_nodata;
which will cause the exponent-adjusted result specified by
IEEE 754 to be substituted. Note that if the handler does
not modify info->res or info->flags, the effect is the same
as if the exception had not been trapped.
Although the default untrapped result of an exceptional
operation is always available to a FEX_CUSTOM handler, in
some cases, one or both operands may not be. In these
cases, the handler may be invoked with info->op1.type ==
fex_nodata or info->op2.type == fex_nodata to indicate that
the respective data structures do not contain valid data.
(For example, info->op2.type == fex_nodata if the excep-
tional operation is a unary operation.) Before accessing
the operand values, a custom handler should always examine
the type field of the operand data structures to ensure that
they contain valid data in the appropriate format.
fex_get_handling(ex) returns the current handling mode for
the exception specified by ex, which must be one of the
first twelve exceptions listed above.
fex_getexcepthandler(buf, ex) saves the current handling
modes and associated data for the exceptions specified by ex
in the data structure pointed to by buf. The type
fex_handler_t is defined in <fenv.h>.
fex_setexcepthandler(buf, ex) restores the handling modes
and associated data for the exceptions specified by ex from
the data structure pointed to by buf. This data structure
must have been set by a previous call to
fex_getexcepthandler(); otherwise the effect on the indi-
cated modes is undefined.
RETURN VALUES
fex_set_handling returns a nonzero value if the requested
exception handling mode is established and returns zero oth-
erwise.
EXAMPLE
The following example shows how to substitute a predeter-
mined value for the result of a 0/0 invalid operation.
#include <math.h>
#include <fenv.h>
double k;
void presub(int ex, fex_info_t *info) {
info->res.type = fex_double;
info->res.val.d = k;
}
int main() {
double x, w;
int i;
fex_handler_t buf;
/*
* save current 0/0 handler
*/
(void) fex_getexcepthandler(&buf, FEX_INV_ZDZ);
/*
* set up presubstitution handler for 0/0
*/
(void) fex_set_handling(FEX_INV_ZDZ, FEX_CUSTOM, presub);
/*
* compute (k*x)/sin(x) for k=2.0, x=0.5, 0.4, ..., 0.1, 0.0
*/
k = 2.0;
(void) printf("Evaluating f(x) = (k*x)/sin(x)\n\n");
for (i = 5; i >= 0; i--) {
x = (double) i * 0.1;
w = (k * x) / sin(x);
(void) printf("\tx=%3.3f\t f(x) = % 1.20e\n", x, w);
}
/*
* restore old 0/0 handler
*/
(void) fex_setexcepthandler(&buf, FEX_INV_ZDZ);
return 0;
}
The output from the preceding program reads:
Evaluating f(x) = (k*x)/sin(x)
x=0.500 f(x) = 2.08582964293348816000e+00
x=0.400 f(x) = 2.05434596443822626000e+00
x=0.300 f(x) = 2.03031801709447368000e+00
x=0.200 f(x) = 2.01339581906893761000e+00
x=0.100 f(x) = 2.00333722632695554000e+00
x=0.000 f(x) = 2.00000000000000000000e+00
Note that when x = 0, f(x) is computed as 0/0 and an invalid
operation exception occurs. In this example, the value 2.0
is substituted for the result.
ATTRIBUTES
See attributes(5) for descriptions of the following attri-
butes:
___________________________________________
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
|____________________|_____________________|
| Availability | SPROm9xs |
| Interface Stability| Stable |
| MT-Level | MT-Safe (see Notes)|
|____________________|_____________________|
SEE ALSO
sigfpe(3), feclearexcept(3M), fegetenv(3M), fex_set_log(3M),
attributes(5)
Numerical Computation Guide
NOTES
In a multi-threaded program, the preceding functions affect
exception handling modes only for the calling thread.
The functions described on this page automatically install
and deinstall SIGFPE handlers and set and clear the trap
enable mode bits in the floating point status register as
needed. If a program uses these functions and attempts to
install a SIGFPE handler or control the trap enable mode
bits independently, the resulting behavior is not defined.
All traps are disabled before a handler installed in
FEX_CUSTOM mode is invoked. When the SIGFPE signal is
blocked, as it is when such a handler is invoked, the float-
ing point environment, exception flags, and retrospective
diagnostic functions described in feclearexcept(3M),
fegetenv(3M), and fex_set_log(3M) do not reenable traps.
Thus, the handler itself always runs in FEX_NONSTOP mode
with logging of retrospective diagnostics disabled.
Attempting to change these modes within the handler may not
produce the expected results.
As shown in the synopsis, the recommended way to link with
libm9x using cc is to specify
-Rinstall-path/lib -Linstall-path/lib -lm9x
on the command line, where install-path refers to the loca-
tion in which the compilers are installed (/opt/SUNWspro by
default). See the Numerical Computation Guide for addi-
tional information about linking with libm9x.