home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / tcpp / examples / matherr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-10  |  5.8 KB  |  142 lines

  1. /*------------------------------------------------------------------------
  2.  * Dateiname - matherr.c
  3.  *
  4.  * Funktion    matherr - Behandlung mathematischer Fehler
  5.  *-----------------------------------------------------------------------*/
  6.  
  7. /*[]---------------------------------------------------[]*/
  8. /*|                                                     |*/
  9. /*|    Turbo C Runtime-Bibliothek                       |*/
  10. /*|                                                     |*/
  11. /*|                                                     |*/
  12. /*|    Copyright (c) 1987,1990 by Borland International |*/
  13. /*|    Alle Rechte vorbehalten.                         |*/
  14. /*|                                                     |*/
  15. /*[]---------------------------------------------------[]*/
  16.  
  17.  
  18. #include <math.h>
  19.  
  20. #ifdef  UNIX_matherr
  21. #include <stdio.h>
  22. #include <process.h>
  23.  
  24. char *whyS [] =
  25. {
  26.     "argument domain error",
  27.     "argument singularity ",
  28.     "overflow range error ",
  29.     "underflow range error",
  30.     "total loss of significance",
  31.     "partial loss of significance"
  32. };
  33.  
  34. /*------------------------------------------------------------------------*
  35.  
  36. Name            matherr - Behandlung mathematischer Fehler
  37.  
  38. Gebrauch        include <math.h>
  39.                 int matherr(struct exception *e);
  40.  
  41. Prototyp in     math.h
  42.  
  43. Beschreibung    Wenn in der Mathematik-Bibliothek Probleme entdeckt werden,
  44.                 wird _matherr() mit allen verfügbaren Informationen aufge-
  45.                 rufen.
  46.  
  47.                 Die Funktion führt relativ wenig aus, sie schreibt die
  48.                 Ursache des Problems (ERANGE oder EDOMAIN) in errno.
  49.                 Sie dient hauptsächlich als Mittelpunkt für Änderungen
  50.                 in der Fehlerbehandlung.
  51.  
  52.                 Wenn Sie zum Beispiel eine Tabellenkalkulation schreiben,
  53.                 könnten Sie diese Funktion durch eine andere ersetzen, die
  54.                 eine Fehlermeldung in einem Fenster zeigt:
  55.  
  56.                         "log (-2.0) caused domain error, in cell J7"
  57.  
  58.                 und dann mit longjmp() in einen Reset-Zustand springen um
  59.                 den nächsten Befehl des Anwenders zu warten.
  60.  
  61.                 Die Standardversion der Turbo C-matherr-Routine meldet
  62.                 keine Underflow- und Precision-Fehler; andere Fehler werden
  63.                 als schwerwiegend angesehen. matherr dient als Grundlage,
  64.                 auf der Sie aufsetzen sollten, wenn Sie Ihre eigene
  65.                 Fehlerbehandlungsroutine schreiben.
  66.  
  67.                 Der Grund für das Nichtmelden der Underflow- und Precision-
  68.                 Fehler ist, daß diese Fehler nicht in ANSI C spezifiziert
  69.                 sind. Daher bekommen Sie
  70.                         exp(-1000) = 0
  71.                         sin(1e100) = NAN
  72.                 ohne Fehler oder Warnung, auch wenn in beiden Fällen die
  73.                 gesamte Rechengenauigkeit verloren geht. Solche Probleme
  74.                 können Sie durch Ihre eigene matherr-Routine abfangen.
  75.  
  76.                 Mögliche Fehler sind DOMAIN, SING, OVERFLOW, UNDERFLOW,
  77.                 TLOSS, PLOSS (in <math.h> aufgeführt). Wie schon oben erklärt,
  78.                 werden UNDERFLOW und TLOSS von der Standard-matherr behandelt.
  79.                 PLOSS wird von Turbo C nicht unterstützt und wird von
  80.                 keiner Bibliotheksfunktion erzeugt.
  81.  
  82.                 Sie können matherr dahingehend modifizieren, daß sie zu
  83.                 einer an Ihre Anwendungen angepaßten Fehler-Routine wird.
  84.                 Sie sollte 0 zurückgeben, wenn es nicht möglich war, einen
  85.                 Fehler zu beheben, und einen Wert ungleich Null, wenn ein
  86.                 Fehler korrigiert worden ist. Wenn matherr 0 zurückgibt, wird
  87.                 weder errno geändert noch eine Fehlermeldung ausgegeben.
  88.  
  89.                 Wir wissen natürlich nicht, welche Fehlerbehandlung Sie
  90.                 möchten, aber Sie können sicher sein, daß alle Fehler mit
  91.                 allen zur Verfügung stehenden Informationen bei matherr() an-
  92.                 kommen, so daß Sie Ihre Lösungen frei gestalten können.
  93.  
  94.                 In Turbo C ist nicht die Funktion matherr() integriert, die
  95.                 UNIX-Benutzer kennen, da der ANSI x3j11 Draft eine inkompa-
  96.                 tible Version unterstützt. Die Version, die Sie erhalten, ist
  97.                 so kompatibel wie möglich, ohne die ANSI-Regeln zu brechen.
  98.                 Natürlich können Sie sie auch in eine UNIX-Version kon-
  99.                 vertieren. Der notwendige Code ist bereits vorhanden, Sie
  100.                 müssen ihn nur noch aktivieren.
  101.  
  102. Rückgabewert    Der Standard-Rückgabewert von matherr ist 0. Matherr kann
  103.                 aber auch e->retval verwenden, was das Ergebnis über
  104.                 _matherr zum Aufrufenden zurückgibt.
  105.  
  106.                 Wenn matherr 0 zurückgibt (und damit meldet, daß der Fehler
  107.                 nicht behoben werden konnte), wird eine Fehlermeldung ausge-
  108.                 geben und Errno ein Wert zugewiesen.
  109.  
  110.                 Wenn matherr einen Wert ungleich Null zurückgibt (und damit
  111.                 meldet, daß der Fehler behoben werden konnte), wird weder
  112.                 eine Meldung ausgegeben noch errno ein Wert zugewiesen.
  113.  
  114. *-------------------------------------------------------------------------*/
  115. int matherr (struct exception *e)
  116. {
  117.     fprintf (stderr,
  118.         "%s (%8g,%8g): %s\n", e->name, e->arg1, e->arg2, whyS [e->type - 1]);
  119.  
  120.     exit (1);
  121. }
  122. #else
  123.  
  124. int matherr(struct exception *e)
  125. {
  126.         if (e->type == UNDERFLOW)
  127.         {
  128.                 e->retval = 0;
  129.                 return 1;
  130.         }
  131.         if (e->type == TLOSS)
  132.         {
  133.                 /* Genauigkeitsverlust, doch das Problem wird ignoriert */
  134.                 return 1;
  135.         }
  136.         /* alle anderen Fehler sind fatal */
  137.         return 0;
  138. }
  139.  
  140.  
  141. #endif
  142.