FEX_SET_HANDLING(3M) Mathematical Library Functions FEX_SET_HANDLING(3M)
fex_set_handling, fex_get_handling, fex_getexcepthandler,
fex_setexcepthandler - control floating point exception handling
modes
c99 [ flag... ] file... -lm [ 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);
These functions provide control of floating point exception handling
modes. For each function, the ex argument specifies 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
The fex_set_handling() function establishes the specified mode for
handling the floating point exceptions identified 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 with
sigfpe(3C).
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 indicates the
operation that caused the exception, info->op1 and info->op2 contain
the values of the operands, info->res contains 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 exception occurred.
The handler might modify info->res and info->flags to supply any
desired result value and flags. Alternatively, if the exception is
underflow or overflow, the handler might set
info->res.type = fex_nodata;
which causes the exponent-adjusted result specified by IEEE 754 to be
substituted. 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 exceptional
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.
The fex_get_handling() function returns the current handling mode for
the exception specified by ex, which must be one of the first twelve
exceptions listed above.
The fex_getexcepthandler() function 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>.
The fex_setexcepthandler() function 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 indicated modes is undefined.
The fex_set_handling() function returns a non-zero value if the
requested exception handling mode is established. Otherwise, it
returns 0.
The following example demonstrates how to substitute a predetermined
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
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.
See attributes(7) for descriptions of the following attributes:
+----------------------------------------------------------+
|ATTRIBUTE TYPE ATTRIBUTE VALUE |
|Availability SUNWlibms, SUNWlmxs |
|Interface Stability Stable |
|MT-Level MT-Safe (see Notes) |
+----------------------------------------------------------+
sigfpe(3C), feclearexcept(3M), fegetenv(3M), fex_set_log(3M),
attributes(7)
Numerical Computation Guide
In a multithreaded application, 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 floating point environment, exception flags,
and retrospective diagnostic functions described in
feclearexcept(3M), fegetenv(3M), and fex_set_log(3M) do not re-enable
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.
SunOS 5.11 December 28, 2020 FEX_SET_HANDLING(3M)
NAME
fex_set_handling, fex_get_handling, fex_getexcepthandler,
fex_setexcepthandler - control floating point exception handling
modes
SYNOPSIS
c99 [ flag... ] file... -lm [ 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 specifies 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
The fex_set_handling() function establishes the specified mode for
handling the floating point exceptions identified 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 with
sigfpe(3C).
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 indicates the
operation that caused the exception, info->op1 and info->op2 contain
the values of the operands, info->res contains 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 exception occurred.
The handler might modify info->res and info->flags to supply any
desired result value and flags. Alternatively, if the exception is
underflow or overflow, the handler might set
info->res.type = fex_nodata;
which causes the exponent-adjusted result specified by IEEE 754 to be
substituted. 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 exceptional
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.
The fex_get_handling() function returns the current handling mode for
the exception specified by ex, which must be one of the first twelve
exceptions listed above.
The fex_getexcepthandler() function 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>.
The fex_setexcepthandler() function 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 indicated modes is undefined.
RETURN VALUES
The fex_set_handling() function returns a non-zero value if the
requested exception handling mode is established. Otherwise, it
returns 0.
EXAMPLES
The following example demonstrates how to substitute a predetermined
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
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(7) for descriptions of the following attributes:
+----------------------------------------------------------+
|ATTRIBUTE TYPE ATTRIBUTE VALUE |
|Availability SUNWlibms, SUNWlmxs |
|Interface Stability Stable |
|MT-Level MT-Safe (see Notes) |
+----------------------------------------------------------+
SEE ALSO
sigfpe(3C), feclearexcept(3M), fegetenv(3M), fex_set_log(3M),
attributes(7)
Numerical Computation Guide
NOTES
In a multithreaded application, 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 floating point environment, exception flags,
and retrospective diagnostic functions described in
feclearexcept(3M), fegetenv(3M), and fex_set_log(3M) do not re-enable
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.
SunOS 5.11 December 28, 2020 FEX_SET_HANDLING(3M)