#include <math.h> int _matherr (struct exception *e)(z.B. Borland und Microsoft C-Systeme)
Die Struktur exception besitzt folgenden Aufbau:
struct exception {
int type; /* Art des Fehlers */
char *name; /* Name der Funktion, in der ein
Fehler aufgetreten ist */
double arg1, arg2, retval; /* 1. und 2. Parameter der Funktion,
Rückgabewert dieser Funktion */
};
Rückgabewert:
1 Funktionswert wurde korrigiert
Programm arbeitet weiter, als wäre kein Fehler aufgetreten
0 Funktionswert wurde nicht korrigiert
Programm führt die vom C-System vorgesehene
Standardfehlerbehandlung aus
Beispiel (Borland C++):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int _matherr (struct exception *e) /* Borland C */
{
char *msg[] =
{
"argument domain error",
"argument singularity ",
"overflow range error ",
"underflow range error",
"total loss of significance",
"partial loss of significance"
};
union nan {
unsigned short NANS[4]; /* NaN = Not a Number */
double NAN; /* NaN = 0x7FF8042000000000 */
} NaN, Infp;
/* NaN = 0x7FF8042000000000 Not a Number */
NaN.s[0] = 0; NaN.s[1] = 0; NaN.s[2] = 0x0420; NaN.s[3] = 0x7FF8;
/* Infp = 0x7FF0000000000000 +Infinite */
Infp.s[0] = 0; Infp.s[1] = 0; Infp.s[2] = 0; Infp.s[3] = 0x7FF0;
fprintf(stderr,
"%s (%8g,%8g): %s\n", e->name, e->arg1, e->arg2, msg[e->type - 1]);
switch ( e->type ) {
case 3:
e->retval = Infp.d; break;
case 4:
e->retval = 0; break;
default:
e->retval = NaN.d; break;
}
return 1;
}
int main(void)
{
printf("sin(1e1) = %f \n", sin(1e1));
printf("sin(1e10) = %f \n", sin(1e10));
printf("sin(1e100) = %f \n", sin(1e100));
printf("\n");
printf("exp(-10) = %f \n", exp(-10));
printf("exp(-100) = %f \n", exp(-100));
printf("exp(-1000) = %f \n", exp(-1000));
printf("\n");
printf("log(0) = %f \n", log(0));
printf("exp(10000) = %f \n", exp(10000));
printf("End\n");
return 0;
}
Testergebnisse mit Borland C++ 4.5
sin(1e1) = -0.544021 sin(1e10) = -0.487506 sin ( 1e+100, 0): total loss of significance sin(1e100) = +NAN exp(-10) = 0.000045 exp(-100) = 0.000000 exp ( -1000, 0): underflow range error exp(-1000) = 0.000000 log ( 0, 0): argument singularity log(0) = +NAN exp ( 10000, 0): overflow range error exp(10000) = +INF EndTestergebnisse mit Borland C++ 4.5 ohne nutzerdefinierte Funktion _matherr
sin(1e1) = -0.544021 sin(1e10) = -0.487506 sin(1e100) = +NAN exp(-10) = 0.000045 exp(-100) = 0.000000 exp(-1000) = 0.000000 log: SING error log(0) = -1.797693134862315708000000000000000000000e+308 exp: OVERFLOW error exp(10000) = 1.797693134862315708000000000000000000000e+308 EndTestergebnisse mit Microsoft C 6.0 ohne nutzerdefinierte Funktion _matherr
sin(1e1) = -0.544021 sin: TLOSS error sin(1e10) = 0.000000 sin: TLOSS error sin(1e100) = 0.000000 exp(-10) = 0.000045 exp(-100) = 0.000000 exp(-1000) = 0.000000 log: SING error log(0) = -179769313486231600000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 000.000000 exp(10000) = 1797693134862316000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00.000000 EndEine alternative Möglichkeit aufgetretene Fehler festzustellen besteht eventuell darin, die Variable errno auszuwerten:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>
void check(void)
{
if ( errno )
printf("errno = %d\n", errno, _sys_errlist[errno]);
}
int main(void)
{
printf("sin(1e100) = %f \n", sin(1e100)); check();
printf("exp(-1000) = %f \n", exp(-1000)); check();
printf("log(0) = %f \n", log(0)); check();
printf("exp(10000) = %f \n", exp(10000)); check();
return 0;
}
Testergebnisse, Borland C++
sin(1e100) = +NAN exp(-1000) = 0.000000 log: SING error log(0) = -1.797693134862315708000000000000000000000e+308 errno = 34 : Result too large exp: OVERFLOW error exp(10000) = 1.797693134862315708000000000000000000000e+308 errno = 34 : Result too largeTestergebnisse, Microsoft Visual C++ 1.0
sin: TLOSS error sin(1e100) = 0.000000 errno = 34 : Result too large exp(-1000) = 0.000000 errno = 34 : Result too large log: SING error log(0) = -179769313486231600000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 000.000000 errno = 34 : Result too large exp(10000) = 1797693134862316000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00.000000 errno = 34 : Result too largeTestergebnisse, Gnu C unter DOS
Floating Point exception at eip=1fdc
eax=00004581 ebx=00054011 ecx=00000000 edx=00000066 esi=00051d20 edi=fffffff3
ebp=00051cf8 esp=00050938 cs=b7 ds=af es=af fs=af gs=c7 ss=bf cr2=00001fea
Call frame traceback EIPs:
0x00001fdc
0x000014ec
0x00001244
Verschiedene C-Systeme stufen Ausnahmesituationen unterschiedlich ein und
nehmen zum Teil sehr unterschiedliche Handlunngen vor.