Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
Vorwort des Gutachters
1 Einstieg in C
2 Das erste Programm
3 Grundlagen
4 Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
5 Basisdatentypen
6 Operatoren
7 Typumwandlung
8 Kontrollstrukturen
9 Funktionen
10 Präprozessor-Direktiven
11 Arrays
12 Zeiger (Pointer)
13 Kommandozeilenargumente
14 Dynamische Speicherverwaltung
15 Strukturen
16 Ein-/Ausgabe-Funktionen
17 Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
19 Zeitroutinen
20 Weitere Headerdateien und ihre Funktionen (ANSI C)
21 Dynamische Datenstrukturen
22 Algorithmen
23 CGI mit C
24 MySQL und C
25 Netzwerkprogrammierung und Cross–Plattform-Entwicklung
26 Paralleles Rechnen
27 Sicheres Programmieren
28 Wie geht’s jetzt weiter?
A Operatoren
B Die C-Standard-Bibliothek
Stichwort

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch
Buch: C von A bis Z

C von A bis Z
3., aktualisierte und erweiterte Auflage, geb., mit CD und Referenzkarte
1.190 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1411-7
Pfeil 20 Weitere Headerdateien und ihre Funktionen (ANSI C)
Pfeil 20.1 <assert.h> – Testmöglichkeiten und Fehlersuche
Pfeil 20.2 <ctype.h> – Zeichenklassifizierung und Umwandlung
Pfeil 20.3 Mathematische Funktionen – <math.h>, <tgmath.h> und <complex.h>
Pfeil 20.3.1 Funktionen für reelle und komplexe Gleitpunkttypen
Pfeil 20.3.2 Funktionen nur für reelle Gleitpunkttypen
Pfeil 20.3.3 Funktionen nur für komplexe Gleitpunkttypen
Pfeil 20.3.4 Typengenerische Makros – <tgmath.h>
Pfeil 20.3.5 Gleitpunktwerte klassifizieren
Pfeil 20.3.6 Makro zum Vergleichen von reellen Zahlen
Pfeil 20.3.7 Zugriff auf die Gleitpunkt-Umgebung – <fenv.h>
Pfeil 20.4 <stdlib.h>
Pfeil 20.4.1 Programmbeendigung – »exit()«, »_exit()«, »atexit()« und »abort()«
Pfeil 20.4.2 Strings in numerische Werte konvertieren
Pfeil 20.4.3 Bessere Alternative – Strings in numerische Werte konvertieren
Pfeil 20.4.4 Zufallszahlen
Pfeil 20.4.5 Absolutwerte, der Quotient und der Rest von Divisionen
Pfeil 20.4.6 Suchen und Sortieren – »qsort()« und »bsearch()«
Pfeil 20.4.7 system()
Pfeil 20.5 <locale.h> – länderspezifische Eigenheiten
Pfeil 20.6 Nicht-lokale Sprünge – <setjmp.h>
Pfeil 20.7 <signal.h>
Pfeil 20.8 <string.h> – die »mem…«-Funktionen zur Speichermanipulation
Pfeil 20.8.1 »memchr()« – Suche nach einzelnen Zeichen
Pfeil 20.8.2 »memcmp()« – bestimmte Anzahl von Bytes vergleichen
Pfeil 20.8.3 »memcpy()« – bestimmte Anzahl von Bytes kopieren
Pfeil 20.8.4 »memmove()« – bestimmte Anzahl von Bytes kopieren
Pfeil 20.8.5 »memset()« – Speicherbereich mit bestimmten Zeichen auffüllen


Rheinwerk Computing - Zum Seitenanfang

20.3 Mathematische Funktionen – <math.h>, <tgmath.h> und <complex.h> Zur nächsten ÜberschriftZur vorigen Überschrift

Die Standard-Bibliothek beinhaltet mittlerweile eine gewaltige Sammlung von mathematischen Funktionen. Die meisten dieser Funktionen sind in der Headerdatei <math.h> deklariert. Die meisten dieser Funktionen sind für Gleitpunktzahlen und zum Teil auch für komplexe Gleitpunkttypen (aus der Headerdatei <complex.h>) geeignet. Zwar bietet die Standard-Bibliothek auch einige Funktionen für ganzzahlige Typen, diese sind aber alle vorwiegend in der Headerdatei <stdlib.h> bzw. für den Typ intmax_t in <inttypes.h> deklariert. Des Weiteren sind in der Headerdatei <tgmath.h> typengenerische Makros definiert, mit denen es möglich ist, mathematische Funktionen mit einem einheitlichen Namen, unabhängig vom Typ der Argumente, aufzurufen.

Um mit den anschließenden Tabellen nicht den Rahmen des Buches zu sprengen, werden zur besseren Übersicht nur die Funktionen für die Gleitpunkttypen double und double _Complex aufgelistet. Zu jeder dieser Funktionen gibt es auch eine Version mit float bzw. float _Complex und eine Version für long double bzw. long double _Complex. Die Versionen von float bzw. float _Complex haben das Suffix f am Ende des Funktionsnamens, und die Versionen für long double bzw. long double _Complex haben das Suffix l am Ende. Sofern Sie allerdings die Headerdatei <tgmath.h> verwenden, können Sie dies außer Acht lassen. Mehr dazu erfahren Sie in Abschnitt 20.3.4.

Wenn ich beispielsweise die Funktion zum Ziehen der Quadratwurzel für reelle Zahlen wie folgt aufliste:

double sqrt(double zahl);

dann existieren von dieser Funktion noch die Versionen:

float sqrtf(float zahl);
long double sqrtl(long double zahl);

Gleiches gilt auch für die aufgelistete komplexe Gleitpunkttyp-Version, nur dass diese Funktionen noch zusätzlich mit dem Präfix c beginnen:

double complex csqrt(double complex z);

Auch von dieser Version gibt es noch zwei weitere Versionen:

float complex csqrtf(float complex z);
long double complex csqrtl(long double complex z);

Hinweis für Linux-User

Damit ein Programm die <math.h>-Bibliothek verwenden kann, muss diese erst mit dem Compiler-Flag -lm hinzugelinkt werden. Beispiel:

gcc -o programm programm.c -lm



Rheinwerk Computing - Zum Seitenanfang

20.3.1 Funktionen für reelle und komplexe Gleitpunkttypen Zur nächsten ÜberschriftZur vorigen Überschrift

In Tabelle 20.2 finden Sie Funktionen aus der Headerdatei <complex.h> und <math.h>, die Sie für reelle und komplexe Gleitpunkttypen verwenden können.


Hinweis

<complex.h> wurde erst mit dem C99-Standard eingeführt, was natürlich wieder heißt, dass der Compiler dies wiederum nur unterstützt, wenn er C99-konform ist.



Tabelle 20.2 Mathematische Funktionen für reelle und komplexe Gleitpunkttypen

Funktion in <math.h> Funktion in <complex.h> Beschreibung
double cosh(
  double z ); 1)  
double sinh(
  double z ); 1)  
double tanh(
  double z); 1)  
double complex ccosh(
  double complex z );
double complex csinh(
  double complex z );
double complex ctanh(
  double complex z);

Hyperbolische Funktionen

double acos(
  double z );
double complex cacos(
  double complex z );

Arcuscosinus

double asin(
  double z );
double complex casin(
  double complex z );

Arcussinus

double atan(
  double z );
double complex catan(
  double complex z );

Arcustangens

double cos(
  double z );
double complex ccos(
  double complex z );

Cosinus

double sin(
  double z );
double complex csin(
  double complex z );

Sinus

double tan(
  double z);
double complex ctan(
  double complex z);

Tangens

double cosh(
  double z);
double complex ccosh(
  double complex z);

Cosinus hyperbolicus

double sinh(
  double z);
double complex casinh(
  double complex z);

Sinus hypberbolicus

double tanh(
  double z);
double complex ctanh(
  double complex z);

Tangens hypberbolicus

double exp(
  double z);
double complex cexp(
  double complex z);

Exponentialfunktion berechnen

double log(
  double z);
double complex clog(
  double complex z);

Logarithmus von z zur Basis e = 2.71828 ...

double sqrt(
  double z);
double complex csqrt(
  double complex z);

Quadratwurzel

double fabs(
  double z);
double cabs(
  double complex z);

Absolutwert

double pow(
  double z1,
  double z2) ;
double complex cpow(
  double complex x,
  double complex y);

Potenz z1z2

1) Diese Funktionen wurden erst mit dem C99-Standard eingeführt.



Rheinwerk Computing - Zum Seitenanfang

20.3.2 Funktionen nur für reelle Gleitpunkttypen Zur nächsten ÜberschriftZur vorigen Überschrift

Die Funktionen in Tabelle 20.3 stehen nur für reelle Gleitpunkttypen zur Verfügung und sind in der Headerdatei <math.h> definiert.


Tabelle 20.3 Mathematische Funktionen für reelle Gleitpunkttypen

Funktion Beschreibung
double atan2(
  double x1, double x2);

Arcustangens von x1 und x2

double exp(double x);
double exp2(double x); 1)  
double frexp(
  double x, int x2);
double ldexp(
   double x, int exp);
double scalbn(
   double x, int n); 1)  
double scalbln(
   double x, long int n); 1)  

Exponentialfunktionen

double log(double x);
double log10(double x)
double log1p(double x); 1)  
double log2(double x); 1)  
double logb(double x); 1)  
int ilogb(double x); 1)  

Logarithmusfunktionen

double fabs(double x);

Absolutwert

double nextafter(
  double x, double y); 1)  
double nexttoward(
  double x, long double y); 1)  

Nächste darstellbare Zahl

double fma(
   double x,
   double y,
   double z); 1)  

Multiplikation und Addition

double fdim(
  double x, double y); 1)  

Positive Differenz

double trunc(double x); 1)  
long long int llround(
   double x); 1)  
long int lround(double x); 1)  
double round(double x); 1)  
long long int llrint(
   double x); 1)  
long int lrint(double x); 1)  
double rint(double x); 1)  
double nearbyint(double x); 1)  

Rundungsfunktionen

double floor(double x);
double ceil(double x);

Nächste Ganzzahl runden

double modf(
  double1 x1, double2 *x2);

Zerlegt den Wert von x1 in einen gebrochenen und einen ganzzahligen Wert. Der ganzzahlige Wert (Vorkommateil) befindet sich dann in der Adresse von x2.

int fmod(
   double x1, double x2);
double remainder(
   double x, double y); 1)  
double remquo(
   double x,
   double y,
   int *quo); 1)  

Rest einer Division

double hypot(
   double x, double y);
double cbrt(double x); 1)  

Wurzelfunktionen

double erf(double x); 1)  
double erfc(double x); 1)  

Fehlerfunktionen zur Normalverteilung

double fmin(
   double x, double y);
double fmax(
   double x, double y);

Minimum und Maximum

double lgamma(double x); 1)  
double tgamma(double x); 1)  

Gammafunktionen

double copysign(
   double x, double y); 1)  

Vorzeichen zuordnen

double nan(
   const char *tagp); 1)  

Ein NaN erzeugen

1) Diese Funktionen wurden erst mit dem C99-Standard eingeführt.



Rheinwerk Computing - Zum Seitenanfang

20.3.3 Funktionen nur für komplexe Gleitpunkttypen Zur nächsten ÜberschriftZur vorigen Überschrift

Zum Schluss fehlt nur noch die Tabelle mit den mathematischen Funktionen aus der Headerdatei <complex.h>, die nur für komplexe Gleitpunkttypen vorhanden sind.


Tabelle 20.4 Mathematische Funktionen für komplexe Gleitpunkttypen

Funktion Beschreibung
double cimag(double complex z);
double creal(double complex z);

der Imaginär- bzw. komplexe Teil der komplexen Zahl

double complex cproj(
  double complex z);

komplexe Projektion auf die Riemann‘sche Sphäre

double complex conj(
  double complex z);

konjugierte komplexe Zahl

double carg(double complex z);

Winkel in den Polarkoordinaten (komplexes Argument)


Hierzu folgt ein einfaches Beispiel, das diese Funktionen in der Praxis demonstrieren soll. Da immer noch diverse Compiler den C99-Standard implementiert haben und somit komplexe Zahlen nicht verwenden können, habe ich hier das Makro zur Überprüfung auf den neueren C99-Standard verwendet.

/* mathematik1.c */
#include <stdio.h>
#include <stdlib.h>
/* bei Linux das Compiler-Flag -lm mit angeben */
#include <math.h>
#if __STDC_VERSION__ >= 19901L
   #include <complex.h>
#endif

int main(void) {
   double i=5.5, pi;
#if __STDC_VERSION__ >= 19901L
   double complex c;
#endif

   // Berechnungen mit reellen Zahlen
   printf("Quadratwurzel von %f = %f\n",i,sqrt(i));
   printf("Der Sinus von %f = %f\n",i,sin(i));
   printf("Der Tangens von %f = %f\n",i,tan(i));
   printf("Der Cosinus von %f = %f\n",i,cos(i));

#if __STDC_VERSION__ >= 19901L
   // Berechnung mit komplexen Zahlen
   pi = 4 * atan(1.0);
   c = cexp(I * pi);
   printf("%f + %f * i\n", creal(c), cimag(c));
#endif
   return EXIT_SUCCESS;
}

Sollte der double-Wert nicht mehr richtig darstellbar sein, geben all diese Funktionen die Konstante HUGE_VAL zurück, die ebenfalls in der Headerdatei <math.h> deklariert ist. Für die float- bzw. long double-Funktionen sind für die Makros HUGE_VALF und HUGE_VALL definiert.


Rheinwerk Computing - Zum Seitenanfang

20.3.4 Typengenerische Makros – <tgmath.h> Zur nächsten ÜberschriftZur vorigen Überschrift

<tgmath.h> wurde mit dem C99-Standard eingeführt. In <tgmath.h> sind die Headerdateien <math.h> und <complex.h> inkludiert und definieren typengenerische Makros. Der Vorteil dieser Makros liegt darin, dass Sie unabhängig vom Typ des Arguments die mathematischen Funktionen mit demselben Namen aufrufen können. Das bedeutet, Sie können außer Acht lassen, welche mathematische Funktionen Sie für den Typ float, double, long double, float complex, double complex und long double complex aufrufen.

Wollen Sie beispielsweise eine Funktion zum Ziehen der Quadratwurzel verwenden, so mussten Sie, abhängig vom Datentyp, zwischen sechs verschiedenen Varianten mit sqrtf(), sqrt(), sqrtl(), csqrtf(), csqrt() und csqrtl() unterscheiden. Mit den typengenerischen Makros in <tgmath.h> brauchen Sie sich darum keine Gedanken mehr machen. Hier müssen Sie lediglich die Funktionen der double- bzw. double complex-Variante kennen, und ein Aufruf von sqrt() führt automatisch die entsprechende Erweiterung aus. Rufen Sie beispielsweise sqrt() mit einem float complex-Argument aus, wird automatisch die Erweiterung csqrtf() ausgeführt.

Hierzu folgt ein Beispiel, das diese typengenerischen Makros demonstrieren soll. In diesem Beispiel wird für alle reellen und komplexen Gleitpunkttypen die Funktion sqrt() zum Ziehen der Quadratwurzel aufgerufen, was ohne die typengenerischen Makros nicht möglich gewesen wäre (und bei Compilern, die den C99-Standard nicht vollständig unterstützen, auch nicht möglich ist). Hier sehen Sie das Listing:

/* mathematik2.c */
#include <stdio.h>
#include <stdlib.h>
/* bei Linux den Compiler-Flag -lm mit angeben */
#include <tgmath.h>

int main(void) {
   float f = 1.1;
   double d=2.2;
   long double ld = 3.3;
   float complex fc = 1.0 + 2.0*I, fcval;
   double complex dc = 4.0 + 2.0*I, dcval;
   long double complex ldc = 8.0 + 9.0*I, ldcval;

   // Berechnungen mit reellen Zahlen
   printf("Quadratwurzel von %f = %f\n",f,sqrt(f));
   printf("Quadratwurzel von %f = %f\n",d,sqrt(d));
   printf("Quadradwurzel von %Lf = %Lf\n",ld,sqrt(ld));
   fcval = sqrt(fc);
   printf("Quadratwurzel von %f + %fi = Lf\n",
      creal(fcval), cimag(fcval));
   dcval = sqrt(dc);
   printf("Quadratwurzel von %f + %fi\n",
      creal(dcval), cimag(dcval));
   ldcval = sqrt(ldc);
   printf("Quadratwurzel von %Lf + %Lfi\n",
      creal(ldcval), cimag(ldcval));
   return EXIT_SUCCESS;
}

Rheinwerk Computing - Zum Seitenanfang

20.3.5 Gleitpunktwerte klassifizieren Zur nächsten ÜberschriftZur vorigen Überschrift

Ein weiteres interessantes Feature sind Makros zur Bestimmung der Kategorie von Gleitpunktzahlen. Seit dem C99-Standard werden die Gleitpunktzahlen in folgende fünf Kategorieren unterteilt (Konstanten aus der Headerdatei <math.h>):


Tabelle 20.5 Bestimmung der Gleitpunktzahl-Kategorie

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:


Tabelle 20.6 Makros zur Bestimmung der Gleitpunktzahl-Kategorie

Makro Bedeutung
isnan(x)

Ist die Gleitpunktzahl gleich FP_NAN, wird 1 zurückgegeben, ansonsten 0.

isnormal(x)

Ist die Gleitpunktzahl gleich FP_NORMAL, wird 1 zurückgegeben, ansonsten 0.

isfinite(x)

Ist die Gleitpunktzahl eine unendliche Zahl, wird 1 zurückgegeben, ansonsten 0.

isinf(x)

Ist die Gleitpunktzahl gleich FP_INFINITE, wird 1 zurückgegeben, ansonsten 0.


Intern werden alle diese Makros jedoch mithilfe des Makros fpclassify() ausgewertet. Selbstverständlich können Sie fpclassify() auch mithilfe der vordefinierten Konstanten wie folgt verwenden:

if ( fpclassify(x) == FP_NORMAL ) {
   /* … */
}
// ... gleichwertig zu ...
if( isnormal(x) ) {
   /* ... */
}

Rheinwerk Computing - Zum Seitenanfang

20.3.6 Makro zum Vergleichen von reellen Zahlen Zur nächsten ÜberschriftZur vorigen Überschrift

Makros zum Vergleichen von Gleitpunktzahlen sind nicht unbedingt nötig. In Abschnitt 5.9, »Numerische Gleitpunktprobleme«, haben Sie bereits erfahren, dass abgesehen von Gleichheit (==) alle Vergleiche von Gleitpunktzahlen möglich sind. Dennoch gibt es noch ein Problem, das hier nicht angesprochen wurde: Ist einer der Werte keine gültige Gleitpunktzahl, lassen sich die Operanden nicht miteinander vergleichen und es wird die Exception FE_INVALID ausgelöst. Wollen Sie vermeiden, dass diese Exception ausgelöst wird, müssen Sie die entsprechenden Makros aus der Headerdatei <math.h> verwenden. Die Makros führen einen stillen Vergleich der Operanden durch, womit keine Exception ausgelöst wird. Tabelle 20.7 zeigt die entsprechenden Makros und deren Bedeutung.


Tabelle 20.7 Makros zum Vergleichen von Gleitpunktzahlen

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.



Rheinwerk Computing - Zum Seitenanfang

20.3.7 Zugriff auf die Gleitpunkt-Umgebung – <fenv.h> topZur vorigen Überschrift

In der Headerdatei <fenv.h> (für Floating Environment = Gleitpunktumgebung) wurden zwei neue Typen, mehrere Makros und einige Funktionen zum Testen auf Fehlersituationen beim Rechnen mit Gleitpunktzahlen implementiert. Diese Umgebung enthält die Systemvariable fexcept_t, die von Gleitpunkt-Exceptions-Funktionen gesetzt werden kann, und die Variable fenv_t, die für den Kontrollmodus (beispielsweise des Rundungsverhaltens) verwendet wird. Die Headerdatei <fenv.h> ist erst seit dem C99-Standard vorhanden.

Um mit dem Programm auf diese Gleitpunkt-Umgebung zuzugreifen, empfiehlt es sich, dies dem Compiler mit dem Pragma STDC FENV_ACCESS mitzuteilen:

// Compiler informieren, damit dieser
// Optimierungen verhindert
#pragma STDC FENV_ACCESS ON

Mit OFF können Sie das Pragma wieder abschalten. Ob dieses Pragma mit dem Status ON oder OFF implementiert ist, hängt vom Compiler ab. Das Pragma ist ebenfalls in der Headerdatei <fenv.h> definiert.

Zugriff auf die Exception-Statusflags

Für den Zugriff auf die Exception-Statusflags von Gleitpunktzahlen stehen Ihnen mehrere Funktionen zur Verfügung, die in Tabelle 20.8 aufgelistet sind.


Tabelle 20.8 Funktionen für den Zugriff auf die Exception-Statusflags

Funktion Beschreibung
int feclearexcept(int excepts);

Exception wieder löschen

int fegetexceptflag(
   fexcept_t *flagp,
   int excepts);

Exception-Statusflags speichern

int feraiseexcept(int excepts);

Exception manuell auslösen

int fesetexceptflag(
   const fexcept_t *flagp,
   int excepts);

Exception-Statusflags wiederherstellen

int fetestexcept(int excepts);

Exception-Statusflags testen


Zur genauen Identifizierung der Exception-Statusflags sind in der Headerdatei <fenv.h> folgende Exceptions als ganzzahlige Makros implementiert:


Tabelle 20.9 Verschiedene Typen von Exceptions in <fenv.h>

Makro Beschreibung
FE_DIVBYZERO

Division durch null

FE_INEXACT

Ungenauigkeit bei der Gleitpunktberechnung

FE_INVALID

ungültige Gleitpunktberechnung

FE_OVERFLOW

Überlauf bei der Gleitpunktberechnung

FE_UNDERFLOW

Unterlauf bei der Gleitpunktberechnung

FE_ALL_EXCEPT

Zugriff auf alle unterstützten Exceptions


Hierzu ein einfaches Beispiel, in dem wir zunächst alle Exception-Statusflags mit der Funktion fegetexceptflag() sichern. Anschließend lösen wir mit Absicht mit einer Division durch 0 die Exception FE_DIVBYZERO aus, was die Überprüfung mit fetestexcept() auch bestätigt. Anschließend stellen wir die zuvor gesicherte Gleitpunkt-Umgebung mit fesetexceptflag() wieder im Ursprungszustand her. Hier sehen Sie das Listing dazu (das natürlich nur bei C99-konformen Compilern läuft):

/* mathematik3.c */
#include <stdio.h>
#include <stdlib.h>
/* bei Linux den Compiler-Flag -lm mit angeben */
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON

int main(void) {
   double d1=0, d2=1.0, dges;
   fexcept_t flagp;
   // Exception-Statusflags sichern
   fegetexceptflag(&flagp, FE_ALL_EXCEPT );
   // mit Absicht eine Division durch 0 auslösen
   dges = d2 / d1;
   if( fetestexcept( FE_DIVBYZERO ) ) {
      printf("Exception ausgelöst: Divsion durch 0 !\n");
   }
   // Exception-Statusflags wiederherstellen
   fesetexceptflag(&flagp, FE_ALL_EXCEPT);
   // Sollte jetzt nicht mehr ausgeführt werden.
   if( fetestexcept( FE_DIVBYZERO ) ) {
      printf("Exception ausgelöst: Divsion durch 0 !\n");
   }
   return EXIT_SUCCESS;
}

Rundungsmodus

Neben den Exception-Statusflags können Sie auch das Rundungsverhalten der Gleitpunktarithmetik mit Funktionen und Makros der Headerdatei <fenv.h> einrichten. Hier sind die beiden dazu nötigen Funktionen:

// Gibt den aktuellen Rundungsmodus zurück,
// gewöhnlich ist hier FE_TONEAREST eingestellt.
int fegetround(void);

// Setzt den Rundungsmodus auf round
// Mögliche Modi dazu finden Sie in der Tabelle 20.10.
int fesetround(int round);

In der Headerdatei <fenv.h> sind die in Tabelle 20.10 aufgelisteten Makros definiert, die von fegetround() zurückgegeben bzw. mit fesetround() gesetzt werden können.


Tabelle 20.10 Mögliche Makros für den Rundungsmodus der Gleitpunktarithmetik

Makro Beschreibung
FE_DOWNWARD

Gleitpunktzahl zum nächsten Integer abrunden

FE_UPWARD

Gleitpunktzahl zum nächsten Integer aufrunden

FE_TONEAREST

Gleitpunktzahl auf nächstmöglichen Integer auf- oder abrunden (Standardeinstellung)

FE_TOWARDZERO

Gleitpunktzahl auf den nächstmöglichen Integer in der Nähe von 0 runden.


Die Verwendung ist entsprechend einfach:

#include <fenv.h>
...
int save;
...
// Rundungsmodus sichern
save = fegetround();
// neuen Rundungsmodus festlegen
fesetround(FE_UPWARD);
...
...
// Rundungsmodus wiederherstellen
fesetround(save);

Zugriff auf die komplette Gleitpunktumgebung

Es gibt auch noch Funktionen, mit denen Sie auf die komplette Gleitpunkt-Umgebung zugreifen können:

// Gleitpunkt-Umgebung speichern
int fegetenv(fenv_t *envp);
// Gleitpunkt-Umgebung in einen Non-Stop-Modus setzen.
// Hierbei unterbricht eine Exception nicht die
// Programmausführung.
int feholdexcept(fenv_t *envp);
// Gleitpunkt-Umgebung wiederherstellen
int fesetenv(const fenv_t *envp);
// eine gespeicherte Gleitpunkt-Umgebung wiederherstellen
// und alle zur Laufzeit gesetzten Exceptions erneut auslösen
int feupdateenv(const fenv_t *envp);


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: C von A bis Z

 C von A bis Z
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: C/C++






 C/C++


Zum Rheinwerk-Shop: Einstieg in C






 Einstieg in C


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: C++ Handbuch






 C++ Handbuch


Zum Rheinwerk-Shop: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
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.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern