BEZEICHNUNG
math_error - Erkennung von Fehlern mathematischer Funktionen
ÜBERSICHT
#include
<math.h>
#include <errno.h>
#include <fenv.h>
BESCHREIBUNG
Wenn ein Fehler eintritt, zeigen die meisten Bibliotheksfunktionen diesen Umstand durch Rückgabe eines speziellen Wertes an (z.B. -1 oder NULL). Weil sie normalerweise eine Fließkomma-Zahl zurückgeben, zeigen die in <math.h> deklarierten Funktionen einen Fehler mit anderen Mechanismen an. Es gibt zwei Mechanismen für das Berichten von Fehlern: Der ältere setzt errno; der neuere wird in fenv(3) beschrieben und nutzt den Fließkomma-Ausnahmemechanismus (die Verwendung von feclearexcept(3) und fetestexcept(3), wie im Folgenden skizziert).
Ein portables Programm, das auf Fehler beim Aufruf mathematischer Funktionen prüfen muss, sollte errno auf Null setzen und
feclearexcept(FE_ALL_EXCEPT);
aufrufen, bevor es eine mathematische Funktion aufruft.
Ist nach Abschluss der mathematischen Funktionen errno ungleich Null oder der folgende Aufruf (siehe fenv(3)) gibt einen Wert ungleich Null zurück
fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW);
trat in der mathematischen Funktion ein Fehler auf.
Im Folgenden werden die Fehlerbedingungen beschrieben, die bei mathematischen Funktionen auftreten können.
Argumentfehler
Ein Argumentfehler liegt vor, wenn einer
mathematischen Funktion ein Argument übergeben wird,
dessen Wert außerhalb des Definitionsbereichs der
Funktion liegt (z.B. ein negatives Argument für
log(3)). Wenn ein Argumentfehler vorliegt, geben
mathematische Funktionen üblicherweise ein NaN
zurück (allerdings geben manche Funktionen in diesem
Fall einen anderen Wert zurück); errno wird auf
EDOM gesetzt und die Fließkomma-Ausnahme
»ungültig« (FE_INVALID) wird
ausgelöst.
Polfehler
Ein Polfehler tritt ein, wenn das mathematische
Ergebnis einer Funktion exakt unendlich ist (z.B. ist der
Logarithmus von 0 minus unendlich). Wenn ein Polfehler
eintritt, gibt die Funktion abhängig vom Typ des
Funktionsergebnisses (double, float oder
long double) den (vorzeichenbehafteten) Wert
HUGE_VAL, HUGE_VALF oder HUGE_VALL
zurück. Das Vorzeichen des Ergebnisses ist das
mathematisch korrekte Vorzeichen für die Funktion.
errno wird auf ERANGE gesetzt und die
Fließkomma-Ausnahme »Division durch Null«
(FE_DIVBYZERO) wird ausgelöst.
Bereichsfehler
Ein Bereichsfehler tritt ein, wenn der Betrag des
Funktionsergebnisses nicht im Ergebnisdatentyp der Funktion
dargestellt werden kann. Der Rückgabewert der Funktion
hängt davon ab, ob der Bereichsfehler ein Überlauf
oder ein Unterlauf war.
Ein Fließkomma-Ergebnis läuft über, wenn das Ergebnis endlich, aber zu groß für die Darstellung im Datentyp des Ergebnisses ist. Wenn ein Überlauf eintritt, gibt die Funktion abhängig vom Typ des Funktionsergebnisses (double, float oder long double) den Wert HUGE_VAL, HUGE_VALF oder HUGE_VALL zurück. errno wird auf ERANGE gesetzt und die Fließkomma-Ausnahme »Überlauf« (FE_OVERFLOW) wird ausgelöst.
Ein Fließkomma-Ergebnis läuft unter, wenn das Ergebnis zu klein für die Darstellung im Datentyp des Ergebnisses ist. Wenn ein Unterlauf eintritt, gibt die Funktion typischerweise 0.0 zurück. (C99 fordert, dass der Rückgabewert einer Funktion »ein von der Implementierung definierter Wert sein muss, dessen Betrag nicht größer als der kleinste normalisierte Wert des spezifizierten Typs ist«.) errno kann auf ERANGE gesetzt und eine Fließkomma-Ausnahme »Unterlauf« (FE_UNDERFLOW) kann ausgelöst werden.
Einige Funktionen geben einen Bereichsfehler zurück, wenn der übergebene Argumentwert oder das korrekte Ergebnis der Funktion subnormal sein würden. Ein subnormaler Wert ist von Null verschieden, aber sein Betrag ist so klein, dass er nicht in normierter Form (d.h. mit einer 1 im signifikantesten Bit der Mantisse) dargestellt werden kann. Die Darstellung einer subnormalen Zahl wird eine oder mehrere führende Nullen in der Mantisse enthalten.
ANMERKUNGEN
Die von C99 und POSIX.1 spezifizierte Kennung math_errhandling wird von der Glibc nicht unterstützt. Diese Kennung soll angeben, welches der beiden Verfahren zur Fehlermeldung (errno, Ausnahmen abrufbar über fettestexcept(3)) verwendet wird. Die Standards fordern, dass mindestens eins im Einsatz ist, erlauben aber, dass beide zur Verfügung stehen. Die aktuelle Situation unter Glibc (Version 2.8) ist etwas chaotisch. Die meisten (aber nicht alle) Funktionen lösen bei Fehlern Ausnahmen aus. Einige setzen zusätzlich errno. Einige Funktionen setzen errno, lösen aber keine Ausnahme aus. Einige wenige Funktionen tun weder das Eine noch das Andere. Weitere Einzelheiten finden Sie auf den zugehörigen Handbuchseiten.
Um die komplizierte Anwendung von errno und fetestexcept(3) bei der Fehlerprüfung zu vermeiden, wird oft empfohlen, stattdessen vor jedem Aufruf die Güte der Argumentwerte zu prüfen. So sorgt beispielsweise der folgende Code dafür, dass das Argument für log(3) kein NaN und nicht Null (ein Polfehler) oder kleiner als Null (ein Argumentfehler) ist.
double x, r; if (isnan(x) || islessequal(x, 0)) { /* Fehlerbehandlung für NaN / Polfehler / Argumentfehler */ } r = log(x);
Die Diskussion auf dieser Seite gilt nicht für die mathematischen Funktionen auf komplexen Zahlen (d.h. solche, die in <complex.h> deklariert werden). Von diesen erwarten C99 and POSIX.1 keine Anzeige von Fehlern.
Die gcc(1)-Option -fno-math-errno bewirkt, dass die ausführbare Datei Implementierungen einiger mathematischer Funktionen verwendet, die schneller als die Standard-Implementierungen sind, aber im Fehlerfall errno nicht setzen. (Die gcc(1)-Option -ffast-math aktiviert ebenfalls -fno-math-errno.) Nach Fehlern kann immer noch mittels fetestexcept(3) gesucht werden.
SIEHE AUCH
gcc(1), errno(3), fenv(3), fpclassify(3), INFINITY(3), isgreater(3), matherr(3), nan(3)
info libc
KOLOPHON
Diese Seite ist Teil der Veröffentlichung 5.07 des Projekts Linux-man-pages. Eine Beschreibung des Projekts, Informationen, wie Fehler gemeldet werden können sowie die aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.
ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von Martin Eberhard Schauer <Martin.E.Schauer [AT] gmx.de> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an <debian-l10n-german [AT] lists.org>.