![]() |
|
|
Mit der Funktion fetestexecept() prüfen Sie, welche der Gleitpunkt-Exceptions (siehe Tabelle B.18) gesetzt sind. Die Funktion feraiseexcept() löst die als Argument eingegebene Gleitpunkt-Exception aus. Mit feclearexcept() löschen Sie eine als Argument angegebene Gleitpunkt-Exception. Die Funktion fegetexceptflag() speichert den aktuellen Status, der angegebenen Exception (erstes Argument) in der Systemvariable pflag. Mit der Funktion fesetexceptflag() hingegen können Sie die Flags in pflag, welche Sie zuvor mit fegetexceptflag() gesichert haben, wieder herstellen. Kontroll-ModusMit dem Kontroll-Modus können Sie bspw. angeben, wie eine Gleitpunktzahl gerundet werden soll. Die Rundungsart können Sie mit den folgenden beiden Funktionen setzen bzw. erfragen: #include <fenv.h> int fegetround(void); int fesetround(int mode); Welche Rundungsart Sie setzen bzw. ermitteln können, wird mit den folgenden symbolischen Konstanten festgelegt:
Gleitpunkt-UmgebungWollen Sie die Gleitpunkt-Umgebung als Ganzes verwenden, stehen Ihnen mit dem Typ fenv_t folgende Funktionen zur Auswahl: #include <fenv.h> int fegetenv(fenv_t *penv); int feholdexcept(fenv_t *penv); int fesetenv(const fenv_t *penv); int feupdateenv(const fenv_t *penv); Mit fegetenv() können Sie die aktuelle Gleitpunkt-Umgebung in penv sichern und mit fsetenv() wiederherstellen bzw. setzen. Bei Verwendung von feholdexcept() wird trotzt einer Exception weitergerechnet. Diese Funktion sichert die aktuelle Gleitpunkt-Umgebung und setzt alle Status-Flags zurück. Bspw.: ... fenv_t env; /* Gleitpunkt-Umgebung speichern */ feholdexcept(&env); ... /* Ein Exeception ist aufgetreten !!! bspw. Division durch 0 */ ... /* Exception löschen */ feclearexcept(FE_DIVIDBYZERO); /* zuvor gesetzte Gleitpunkt –Umgebung wieder setzen */ feupdateenv(&env); ... Wie im Code-Auschnitt eben gesehen, wird mit der Funktion feuptdateenv() die übergebene Gleitpunkt-Umgebung wieder gesetzt. Für die Funktionen feudateenv() und fesetenv() kann auch die symbolische Konstante FE_DFL_ENV verwendet werden, was ein Zeiger auf die Gleitpunkt-Umgebung darstellt, welcher beim Programmstart gesetzt wurde. Um die Gleitpunkt-Umgebung überhaupt verwenden zu können, müssen Sie diese mit dem folgenden Pragma aktivieren: #pragma STDC FENC_ACCESS ON B.2.6 <inttypes.h> – Für genauere Integertypen
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Makro | Bedeutung |
| Bool | Boolescher Datentyp für Wahrheit |
| false | 0/trifft nicht zu |
| true | 1/trifft zu |
In der Headerdatei <stdint.h> befinden sich weitere Ganzzahl-Datentypen, die mit vorgegebener Breite verwendet werden. Mit vorgegebener Breite ist die Anzahl der Bits zur Darstellung des Werts gemeint, welche dieser Typ verwenden darf. Hier die Typen im Überblick:
| Typ | Bedeutung |
| intN_t | Ein int-Wert mit einer Breite von exakt N Bits (erlaubte Werte für N: 8, 16, 32, 64) |
| int_leastN_t | Ein int-Wert mit einer Breite von mindestens N Bits (erlaubte Werte für N: 8, 16, 32, 64) |
| int_fastN_t | Der schnellste int-Typ mit mind. einer Breite von N Bits (erlaubte Werte für N: 8, 16, 32, 64) |
| intmax_t | Größtmöglicher ganzzahliger Typ (Wert ist in der Konstante INT64_MAX bzw. UINT64_MAX deklariert) |
| intptr_t | Max. Breite, um den Wert eines Zeigers zu speichern |
Zu all diesen Ganzzahltypen gibt es jeweils einen unsigned-Bruder, der nur ein u vorangestellt hat (z. B. uintptr_t). Die maximalen und minimalen Limits dieser Ganzzahltypen sind ebenfalls in der Headerdatei <stdint.h> deklariert.
Enorm erweitert wurde die Headerdatei <math.h>. Darin befinden sich jetzt noch mehr Funktionen und Makros als zuvor. Zu allen Funktionen, die Sie bereits kennen und denen, welche Sie in diesem Abschnitt noch kennen lernen, wurden Versionen herausgebracht, die jetzt auch für die Datentypen float und long double anwendbar sind. Bisher waren die Funktionen dieser Headerdatei ja nur mit double angegeben. Um die für den Datentyp passende Funktion zu verwenden, müssen Sie nur ein entsprechendes Suffix notieren. f steht für float, l für long double und keine Angabe steht – wie gehabt – für double-Gleitpunktzahlen. Als Beispiel die Funktion sqrt():
float sqrtf(float zahl); /* float */ double sqrt(double zahl); /* double */ long double sqrtl(long double zahl); /* long double */
In der folgenden Tabelle finden Sie einige Funktionen, die neu in die Headerdatei <math.h> hinzugekommen sind. Zu all diesen Funktionen gibt es auch schon verschiedene Versionen. Es hängt davon ab, welches Suffix Sie verwenden.
| Funktionen | Bedeutung |
| double round (double); double trunc (double); double rint (double) | Funktionen zum Runden von Zahlen |
| double fmax (double, double); double fmin (double, double); | Maximum, Minimum |
| double log2 (double); double logb (double); | Logarithmus |
| double copysign (double, double); | Vorzeichen kopieren |
| double scalb (double, long); extern double fma (double, double, double); | Laufzeitoptimierte Berechnungen |
| double hypot (double, double); | Wurzel |
Sehr interessant dürften die Makros für den Vergleich von Gleitpunktzahlen sein, welche ebenfalls hinzugekommen sind:
| Makro | Bedeutung |
| isgreater(x, y) | x größer als y |
| isgreaterequal(x, y) | x größer als oder gleich y |
| isless(x, y) | x kleiner als y |
| islessequal(x, y) | x kleiner als oder gleich y |
| islessgreater(x, y) | x kleiner als y ODER x größer als y |
| isunordered(x, y) | Sind x und y nicht miteinander vergleichbar, gibt dieses Makro 1 zurück, ansonsten 0 |
Ein weiteres interessantes Feature sind Makros zu Bestimmung der Kategorie von Gleitpunktzahlen. In ANSI C werden die Gleitpunktzahlen in folgende fünf Kategorieren unterteilt (Konstanten aus der Headerdatei <math.h>):
| Konstante | Kategorie |
| FP_NAN | NAN steht für Not a Number und bedeutet, dass es sich bei dem Wert um keine gültige Gleitpunktdarstellung handelt. |
| FP_NORMAL | Eine Gleitpunktzahl in normaler Darstellung |
| FP_INFINITE | Die Gleitpunktzahl wird als unendlicher Wert dargestellt. |
| FP_ZERO | Eine Gleitpunktzahl mit dem Wert 0 |
| FP_SUBNORMAL | Eine Gleitpunktzahl, mit der besonders kleine Zahlen dargestellt werden können |
Abfragen, in welche Kategorie eine bestimmte Gleitpunktzahl fällt, können Sie mit den folgenden Makros vornehmen:
| Makro | Bedeutung |
| isnan(x) | Ist die Zahl gleich FP_NAN, wird 1 zurückgegeben, ansonsten 0. |
| isnormal(x) | Ist die Zahl gleich FP_NORMAL, wird 1 zurückgegeben, ansonsten 0. |
| isfinite(x) | Ist die Zahl eine Unendliche, wird 1 zurückgegeben, ansonsten 0. |
| isinf(x) | Ist die Zahl gleich FP_INFINITE, wird 1 zurückgegeben, ansonsten 0. |
Intern werden all diese Makros jedoch zum Teil mit Hilfe des Makros fpclassify() ausgewertet:
fpclassify(x) == FP_INFINITE //isinf(x) fpclassify(x) == FP_NORMAL //isnormal(x)
In der Headerdatei <tgmath.h> befinden sich typengenerische Mathematik-Funktionen (bzw. Makros). Darunter versteht man, dass Sie verschieden mathematische Funktionen mit verschiedenen Argumenten wie reelle und/oder komplexe Gleitpunkttypen mit demselben Namen aufrufen können – es wird also immer die Funktion aufgerufen, welche dem Datentyp des Argumentes entspricht. Bspw.:
float _Complex fx; long double lx; /* gleich zu cos((double)1) */ cos(1) ; /* gleich zu cosl(lx) */ cos(lx) ; /* gleich zu cpowl((long double _Complex)fx, (long double _Complex)lx) */ pow(fx, lx) ;
Ist eine Funktion hingegen nur für reelle und/oder komplexe Gleitpunkttypen definiert, dann entspricht der Namen des typengenerierten Makros dem der Funktion, welche ursprünglich für double definiert ist.
| << zurück |
|
||||||||||||
|
||||||||||||
|
||||||||||||
Copyright © Rheinwerk Verlag GmbH 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich
ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen,
wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist
urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der
Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und
Verarbeitung in elektronischen Systemen.