matherr
Purpose
Performs an action when a math subroutine encounters an
error.
Library
Math Library (libm.a)
Syntax
#include <math.h>
int matherr (excp)
struct exception *excp;
Description
If matherr error handling is in effect, then the math
library subroutines call matherr when an error is
detected. See "exp, log, log10, pow, sqrt" and "sin,
cos, tan, asin, acos, atan, atan2" about alternative
error handling available for these subroutines.
You can override the default error-handling actions by
supplying a subroutine of your own in place of the
matherr subroutine supplied in the math library. To do
this, include in your program a subroutine named matherr
that takes one parameter: a pointer to an exception
structure. The exception structure is defined in the
math.h header file and it contains the following members:
int type;
char *name;
double arg1, arg2, retval;
The structure member named type describes the type of
error that occurred. Its value is one of the following
constants:
DOMAIN Domain error
SING Singularity
OVERFLOW Overflow
UNDERFLOW Underflow
TLOSS Total loss of significance
PLOSS Partial loss of significance
The name member points to a string containing the name of
the subroutine that encountered the error. The members
arg1 and arg2 contain the parameters that were passed to
the subroutine. The retval member is the value that the
math subroutine returns.
All of the math subroutines that call matherr do so in
ways similar to this:
/*
** Set up the exception structure
*/
exc.type = DOMAIN; /* Type of error */
exc.name = "pow"; /* Name of subroutine */
exc.arg1 = x; /* Arguments to pow(x,y) */
exc.arg2 = y;
if (matherr(&exc) == 0)
{
/*
** matherr returned 0, so perform the
** default error-handling procedures
*/
fprintf(stderr, "pow: DOMAIN error\n");
exc.retval = 0;
errno = EDOM;
}
return (exc.retval);
Studying this sample shows that the return value from the
matherr subroutine controls whether or not the math sub-
routine performs its default error-handling procedures.
If matherr returns 0, then the default procedures are
performed. Note in particular that if you want to
specify the value to be returned by the math subroutine,
then your matherr subroutine must set excp"->"retval and
return a nonzero value.
If you do not supply your own matherr subroutine, then
the matherr subroutine supplied in the math library is
linked into your program. This subroutine does nothing
except return the value 0. Because it returns 0, the
calling math subroutine then performs its default error-
handling procedures. The default procedures are men-
tioned in the discussion of each math subroutine.
The math library subroutines atan, ceil, erf, erfc, fabs,
floor, fmod, and tanh do not generate any of the error
types listed on page 3-287 and therefore do not call
matherr.
The following table shows the default error-handling pro-
cedures for the remaining math library subroutines:
+-------+--------+---------+----------+-----------+-------+-------+
| | DOMAIN | SING | OVERFLOW | UNDERFLOW | TLOSS | PLOSS |
+-------+--------+---------+----------+-----------+-------+-------+
| acos | M,0,D(1| -- | -- | -- | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| asin | M,0,D(1| -- | -- | -- | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
Figure 3-3 (Part 1 of 2). Default Error-Handling Proce-
dures
+-------+--------+---------+----------+-----------+-------+-------+
| | DOMAIN | SING | OVERFLOW | UNDERFLOW | TLOSS | PLOSS |
+-------+--------+---------+----------+-----------+-------+-------+
| atan2 | M,0,D(2| -- | -- | -- | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| cos | -- | -- | -- | -- | M,0,R | *,R |
+-------+--------+---------+----------+-----------+-------+-------+
| cosh | -- | -- | H,R | -- | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| exp | -- | -- | H,R | 0,R | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| gamma | -- | M,H,D(3)| H,R | -- | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| hypot | -- | -- | H,R | -- | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| j0 | -- | -- | -- | 0,R | M,0,R | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| j1 | -- | -- | -- | 0,R | M,0,R | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| jn | -- | -- | -- | 0,R | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| log | M,-H,D(|)M,-H,D(5| -- | -- | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| log10 | M,-H,D(|)M,-H,D(5| -- | -- | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| pow | M,0,D(6| -- | AH,R | 0,R | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| sin | -- | -- | -- | -- | M,0,R | *,R |
+-------+--------+---------+----------+-----------+-------+-------+
| sinh | -- | -- | AH,R | -- | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| sqrt | M,0,D(7| -- | -- | -- | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| tan | -- | -- | -- | -- | M,0,R | *,R |
+-------+--------+---------+----------+-----------+-------+-------+
| y0 | M,-H,D(|)-- | -H,R(9) | 0,R | M,0,R | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| y1 | M,-H,D(|)-- | -- | 0,R | M,0,R | -- |
+-------+--------+---------+----------+-----------+-------+-------+
| yn | M,-H,D(|)-- | -H,R(9) | 0,R | -- | -- |
+-------+--------+---------+----------+-----------+-------+-------+
Figure 3-3 (Part 2 of 2). Default Error-Handling Proce-
dures
The following abbreviations are used in the table:
* As much as possible of the value is returned.
0 Zero is returned.
H HUGE is returned.
-H -HUGE is returned.
AH HUGE or -HUGE is returned.
M A message is written to stdout.
D errno is set to EDOM.
R errno is set to ERANGE.
Notes:
(1) Caused by passing acos or asin a value larger than
1.0.
(2) Caused by trying to calculate atan2(0, 0).
(3) Caused by passing gamma a nonpositive integer.
(4) Caused by passing log or log10 a negative value.
(5) Caused by trying to calculate log(0) or log10(0).
(6) Caused by trying to raise a negative number to a non-
integer power or 0 to a nonpositive power.
(7) Caused by passing sqrt a negative value.
(8) Caused by passing y0, y1, or yn a nonpositive value.
(9) Caused by passing y0 a very small positive value.
Examples
The following subroutine suggests the kinds of actions
that a user-supplied matherr subroutine might perform.
It is not the matherr subroutine that is provided in the
math library. The supplied matherr subroutine merely
returns 0.
int matherr(x)
register struct exception *x;
{
switch (x->type)
{
case DOMAIN:
case SING:
/* Display message and abort */
fprintf(stderr, "domain error in %s\n", x->name);
abort();
case OVERFLOW:
if (strcmp("exp", x->name) == 0)
{
/* If exp, display message & return the argument */
fprintf(stderr, "exp of %f\n", x->arg1);
x->retval = x->arg1;
}
else
if (strcmp("sinh", x->name) == 0)
{
/* If sinh, set errno, return 0 */
errno = ERANGE;
x->retval = 0;
}
else
/* Otherwise, return HUGE */
x->retval = HUGE;
break;
case UNDERFLOW:
return (0); /* Perform the default procedures */
case TLOSS:
case PLOSS:
/* Display message and return 0 */
fprintf(stderr, "loss of significance in %s\n",
x->name);
x->retval = 0;
break;
} /* switch */
return (1); /* Do NOT perform the default procedures */
} /* matherr */
Related Information
In this book: "math.h."