Man Page fex_setexcepthandler.3m




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.