'\" t .\" @(#)fex_set_handling.3m 1.4 00/01/01 SMI .TH fex_set_handling 3M "01/01/00" .if n \{ .ds i infinity\} .if t \{ .ds i \(if\} .SH NAME fex_set_handling, fex_get_handling, fex_getexcepthandler, fex_setexcepthandler \- control floating point exception handling modes .SH SYNOPSIS .LP .B cc .RI "[ " "flag" " \|.\|.\|. ] " "file" " \|.\|.\|." .B -R/opt/SUNWspro/lib -L/opt/SUNWspro/lib -lm9x .RI "[ " "library" " \|.\|.\|. ]" .LP .B #include .LP .BI "int fex_set_handling(int " ex ", int " mode ", void" .BI (* handler )(\|)); .LP .BI "int fex_get_handling(int " ex ); .LP .BI "void fex_getexcepthandler(fex_handler_t *" buf ", int " ex ); .LP .BI "void fex_setexcepthandler(const fex_handler_t *" buf ", int " ex ); .SH DESCRIPTION .IX "fex_set_handling function" "" "\fLfex_set_handling()\fP function" .IX "fex_get_handling function" "" "\fLfex_get_handling()\fP function" .IX "fex_getexcepthandler function" "" "\fLfex_getexcepthandler()\fP function" .IX "fex_setexcepthandler function" "" "\fLfex_setexcepthandler()\fP function" .LP These functions provide control of floating point exception handling modes. For each function, the \f2ex\f1 argument specifies one or more exceptions indicated by a bitwise "or" of any of the following values (defined in \f3\f1): .LP .RS .PD 0 .TP 20 \s-1FEX_INEXACT\s0 .TP \s-1FEX_UNDERFLOW\s0 .TP \s-1FEX_OVERFLOW\s0 .TP \s-1FEX_DIVBYZERO\s0 division by zero .TP \s-1FEX_INV_ZDZ\s0 0/0 invalid operation .TP \s-1FEX_INV_IDI\s0 \*i/\*i invalid operation .TP \s-1FEX_INV_ISI\s0 \*i\-\*i invalid operation .TP \s-1FEX_INV_ZMI\s0 0*\*i invalid operation .TP \s-1FEX_INV_SQRT\s0 square root of negative operand .TP \s-1FEX_INV_SNAN\s0 signaling NaN .TP \s-1FEX_INV_INT\s0 invalid integer conversion .TP \s-1FEX_INV_CMP\s0 invalid comparison .PD .RE .LP For convenience, the following combinations of values are also defined: .LP .RS .PD 0 .TP 20 \s-1FEX_NONE\s0 no exceptions .TP \s-1FEX_INVALID\s0 all invalid operation exceptions .TP \s-1FEX_COMMON\s0 overflow, division by zero, and invalid operation .TP \s-1FEX_ALL\s0 all exceptions .PD .RE .LP \f3fex_set_handling(\f2ex\f3, \f2mode\f3, \f2handler\f3)\f1 establishes the specified \f2mode\f1 for handling the floating point exceptions identified by \f2ex\f1. The selected \f2mode\f1 determines the action to be taken when one of the indicated exceptions occurs. It must be one of the following values: .LP .RS .TP 20 \s-1FEX_NOHANDLER\s0 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 \f2handler\f1 parameter is ignored.) .TP \s-1FEX_NONSTOP\s0 Provide the \s-1IEEE\s0 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 \f2handler\f1 parameter is ignored.) .TP \s-1FEX_ABORT\s0 Call \f3abort\f1(3C). (The \f2handler\f1 parameter is ignored.) .TP \s-1FEX_SIGNAL\s0 Invoke the function *\f2handler\f1 with the parameters normally supplied to a signal handler installed via \f3sigfpe\f1(3). .TP \s-1FEX_CUSTOM\s0 Invoke the function *\f2handler\f1 as described in the next paragraph. .RE .LP In \s-1FEX_CUSTOM\s0 mode, when a floating point exception occurs, the handler function is invoked as though its prototype were: .LP .RS .nf \f3#include \f1 .LP \f3void handler(int ex, fex_info_t *info);\f1 .fi .RE .LP On entry, \f3ex\f1 is the value (of the first twelve listed above) corresponding to the exception that occurred, \f3info->op\f1 indicates the operation that caused the exception, \f3info->op1\f1 and \f3info->op2\f1 contain the values of the operands, \f3info->res\f1 contains the default untrapped result value, and \f3info->flags\f1 reflects the exception flags that the operation would have set had it not been trapped. If the handler returns, the value contained in \f3info->res\f1 on exit is substituted for the result of the operation, the flags indicated by \f3info->flags\f1 are set, and execution resumes at the point where the exception occurred. The handler may modify \f3info->res\f1 and \f3info->flags\f1 to supply any desired result value and flags. Alternatively, if the exception is underflow or overflow, the hander may set .LP .RS \f3info->res.type = fex_nodata;\f1 .RE .LP which will cause the exponent-adjusted result specified by \s-1IEEE\s0 754 to be substituted. Note that if the handler does not modify \f3info->res\f1 or \f3info->flags\f1, the effect is the same as if the exception had not been trapped. .LP Although the default untrapped result of an exceptional operation is always available to a \s-1FEX_CUSTOM\s0 handler, in some cases, one or both operands may not be. In these cases, the handler may be invoked with \f3info->op1.type == fex_nodata\f1 or \f3info->op2.type == fex_nodata\f1 to indicate that the respective data structures do not contain valid data. (For example, \f3info->op2.type == fex_nodata\f1 if the exceptional operation is a unary operation.) Before accessing the operand values, a custom handler should always examine the \f3type\f1 field of the operand data structures to ensure that they contain valid data in the appropriate format. .LP \f3fex_get_handling(\f2ex\f3)\f1 returns the current handling mode for the exception specified by \f2ex\f1, which must be one of the first twelve exceptions listed above. .LP \f3fex_getexcepthandler(\f2buf\f3, \f2ex\f3)\f1 saves the current handling modes and associated data for the exceptions specified by \f2ex\f1 in the data structure pointed to by \f2buf\f1. The type \f3fex_handler_t\f1 is defined in \f3\f1. .LP \f3fex_setexcepthandler(\f2buf\f3, \f2ex\f3)\f1 restores the handling modes and associated data for the exceptions specified by \f2ex\f1 from the data structure pointed to by \f2buf\f1. This data structure must have been set by a previous call to \f3fex_getexcepthandler(\|)\f1; otherwise the effect on the indicated modes is undefined. .SH "RETURN VALUES" \f3fex_set_handling\f1 returns a nonzero value if the requested exception handling mode is established and returns zero otherwise. .SH EXAMPLE The following example shows how to substitute a predetermined value for the result of a 0/0 invalid operation. .LP .RS .nf .vs 11p .ft B #include #include 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); .ne 3 /* * 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; } .vs .fi .RE .LP The output from the preceding program reads: .LP .RS .nf .vs 11p .ft B 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 .vs .fi .RE .LP Note that when \f2x\f1 = 0, \f2f(x)\f1 is computed as 0/0 and an invalid operation exception occurs. In this example, the value 2.0 is substituted for the result. .SH ATTRIBUTES See .BR attributes (5) for descriptions of the following attributes: .sp .ne 10 .TS box; cbp-1 | cbp-1 l | l . ATTRIBUTE TYPE ATTRIBUTE VALUE = Availability SPROm9xs Interface Stability Stable MT-Level MT-Safe (see Notes) .TE .SH "SEE ALSO" .BR sigfpe (3), .BR feclearexcept (3M), .BR fegetenv (3M), .BR fex_set_log (3M), .BR attributes (5) .LP .I Numerical Computation Guide .SH NOTES In a multi-threaded program, the preceding functions affect exception handling modes only for the calling thread. .LP The functions described on this page automatically install and deinstall \s-1SIGFPE\s0 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 \s-1SIGFPE\s0 handler or control the trap enable mode bits independently, the resulting behavior is not defined. .LP All traps are disabled before a handler installed in \s-1FEX_CUSTOM\s0 mode is invoked. When the \s-1SIGFPE\s0 signal is blocked, as it is when such a handler is invoked, the floating point environment, exception flags, and retrospective diagnostic functions described in \f3feclearexcept\f1(3M), \f3fegetenv\f1(3M), and \f3fex_set_log\f1(3M) do not reenable traps. Thus, the handler itself always runs in \s-1FEX_NONSTOP\s0 mode with logging of retrospective diagnostics disabled. Attempting to change these modes within the handler may not produce the expected results. .LP As shown in the synopsis, the recommended way to link with libm9x using \f3cc\f1 is to specify .LP .RS .BI -R install-path "/lib -L" install-path "/lib -lm9x" .RE .LP on the command line, where \f2install-path\f1 refers to the location in which the compilers are installed (/opt/SUNWspro by default). See the \f2Numerical Computation Guide\f1 for additional information about linking with libm9x.