www.delorie.com/djgpp/doc/libc/libc_557.html   search  
libc.a reference

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]



#include <libm/math.h>

enum fdversion _fdlib_version = _SVID_;

int matherr(struct exception *exc);


matherr is a user-definable handler for errors in math library functions. It is only supported in the alternate math library (link with `-lm'), and will only be called if the global variable _fdlib_version is set to either _SVID_ or _XOPEN_ (see section libm). You also need to mask the Invalid Operation exception in the x87 control word (see section _control87) or install a handler for signal SIGFPE (see section signal), or else some exceptions will generate SIGFPE and your program will be terminated before it gets a chance to call matherr. DJGPP versions 2.02 and later mask all FP exceptions at startup, so this consideration applies only to programs that unmask FP exceptions at run time.

If the above conditions are met, every math function will call matherr when a numerical exception is detected. The default version of matherr, supplied with `libm.a', does nothing and returns zero (the _SVID_ version will then print an error message to the standard error stream and set errno).

This default behavior is inappropriate in some cases. For example, an interactive program which runs in a windowed environment might want the error message to go to a particular window, or pop up a dialog box; a fault-tolerant program might want to fall back to backup procedures so that meaningful results are returned to the application code, etc. In such cases, you should include your own version of matherr in your program.

matherr is called with a single argument exc which is a pointer to a structure defined on <libm/math.h> like this:

struct exception {
	int type;
	char *name;
	double arg1, arg2, retval;

The member type is an integer code describing the type of exception that has occured. It can be one of the following:

Argument(s) are outside the valid function domain (e.g., log(-1)).

Argument(s) would result in a singularity (e.g., log(0)).

The result causes overflow, like in exp(10000).

The result causes underflow, like in exp(-10000).

The result loses all significant digits, like in sin(10e100).

These codes are defined on <libm/math.h>.

The member name points to the string that is the name of the function which generated the exception. The members arg1 and arg2 are the values of the arguments with which the function was called (arg2 is undefined if the function only accepts a single argument). The member retval is set to the default value that will be returned by the math library function; matherr can change it to return a different value.

Return Value

matherr should return zero if it couldn't handle the exception, or non-zero if the exception was handled.

If matherr returns zero, under _SVID_ version an error message is printed which includes the name of the function and the exception type, and under _SVID_ and _XOPEN_ errno is set to an appropriate value. If matherr returns non-zero, no error message is printed and errno is left unchanged.




  #include <libm/math.h>

  int matherr(register struct exception *x)
    switch (x->type) {
      case DOMAIN:
        /* change sqrt to return sqrt(-arg1), not NaN */
        if (!strcmp(x->name, "sqrt")) {
          x->retval = sqrt(-x->arg1);
          return 1; /* be silent: no message, don't set errno */
        } /* FALL THROUGH */
      case SING:
        /* all other domain or sing exceptions,
         * print message and abort */
        fprintf(stderr, "domain exception in %s\n", x->name);
    return 0; /* all other exceptions, execute default procedure */

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2004   by DJ Delorie     Updated Apr 2004