
#include <lcmath.h> int _matherr(struct exception *x);
_matherr is called whenever one of the other math functions detects an
error. Upon entry, it receives an exception block that describes the error in
detail. This structure is defined in <lcmath.h>:
struct exception {
int type; /* error type */
char *name; /* name of function having error */
double arg1; /* first argument */
double arg2; /* second argument */
double retval; /* proposed return value */
};
The error type names defined in <lcmath.h> are
Error Type Definition
DOMAIN domain error
SING singularity
OVERFLOW overflow
UNDERFLOW underflow
TLOSS total loss of significance
PLOSS partial loss of significance
_matherr returns 0, a diagnostic message is written to the standard
error file (stderr). If _matherr returns a nonzero value, the
diagnostic message is suppressed, and the calling function is forced to accept
a new value from retval.
Traditional UNIX C compilers support the functionality of _matherr using the
name matherr. Unfortunately, using the name matherr
conflicts with the ANSI Standard. However, the header file lcmath.h
contains the following macro:
#define matherr _matherrIf you include this header file, use the name that is compatible with traditional UNIX C compilers.
_matherr supplied in the library places the
appropriate error number into the external integer errno and returns 0.
When _matherr is called, the function that detected the error
places its proposed return value into the exception structure. The 0 return
code indicates that the return value should be used.
Supply your own version of _matherr if desired. On particular
errors, it may be desirable to cause the function detecting the error to return
a value other than its usual default. You can accomplish this by storing a new
return value in retval of the exception structure and then returning a
nonzero value from _matherr, which forces the function to pick up the new
value from the exception structure. If a nonzero value is returned, a
diagnostic message is not printed for the error.
#include <lcmath.h>
#include <lcio.h>
#include <lclib.h>
/* user status flags */
#define ERROR_OK 9000
#define ERROR_WARNING 9001
#define ERROR_SEVERE 9002
/* global status flag */
int status;
/* user-defined math status handler */
int _matherr(struct exception *err)
{
err->retval = -1;
/* Check to see if an error occurred */
/* in the call to sqrt. */
if (strcmp(err->name, "sqrt") == 0)
status = ERROR_SEVERE;
/* Check to see if an error occurred */
/* in the call to log or log10. */
else if (strncmp(err->name, "log", 3) == 0)
status = ERROR_WARNING;
else status = ERROR_OK;
return(1);
}
main()
{
double x, y;
while (feof(stdin) == 0) {
/* Read data and echo it. */
scanf("%f", &x);
printf("necho: x = %fn", x);
y = cosh(x);
/* If no unexpected error occurred, print result. */
if (warning() == 0)
printf("result = %fn", y);
y = log10(x);
/* If no unexpected error occurred, print result. */
if (warning() == 0)
printf("result = %fn", y);
y = sqrt(x);
/* If no unexpected error occurred, print result. */
if (warning() == 0)
printf("result = %fn", y);
} /* End while loop. */
return(0);
}
int warning(void)
{
if (status == ERROR_SEVERE) {
printf("A severe error occurred. status condition = %d"
" ***All processing is terminated***n", status);
exit(EXIT_FAILURE);
}
else if (status == ERROR_WARNING) {
puts("An error occurred; processing will continue.");
status = ERROR_OK;
return(1);
}
status = ERROR_OK;
return(0);
}
quiet
Copyright (c) 1998 SAS Institute Inc. Cary, NC, USA. All rights reserved.