forked from pittlerf/ckurs2017
-
Notifications
You must be signed in to change notification settings - Fork 1
/
standartbibliothek.tex
152 lines (136 loc) · 7.42 KB
/
standartbibliothek.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
\section{Die Bibliotheken \texttt{math.h} und \texttt{complex.h}}
Die Sprache \texttt{C} hat neben den Sprachbestandteilen auch eine umfangreiche Liste von Standardbibliotheken.
Sie sind im \texttt{ANSI C} Standard festgelegt.
Diejenige für die Ein- und Ausgabe haben wir schon kennengelernt.
Wir werden jetzt noch zwei weitere kurz einführen.
\subsection{Mathematische Bibliothek \texttt{math.h}}
Erstens die Bibliothek \texttt{math.h}.
Sie stellt mathematische Funktionen, wie beispielsweise trigonometrische Funktionen, aber auch eine Funktion für den Betrag zur Verfügung.
Natürlich berechnen diese Funktionen das Ergebnis nur zur gewünschten Genauigkeit.
Wir illustrieren dies am Bespiel vom Cosinus.
Die Cosinus Funktion ist auf ganz $\mathbb{R}$ durch eine Taylorreihe um 0 definiert.
\begin{equation}
\label{eq:cos}
\cos\left(x\right)\ =\ \sum_{l=0}^{\infty} \left(-1\right)^{l} \dfrac{x^{2l}}{\left(2l\right)!}\,.
\end{equation}
Die Funktion
\begin{lstlisting}
double cos(double x);
\end{lstlisting}
berechnet den Cosinus in \texttt{double} Genauigkeit.
Im folgenden Quelltext berechnen wir den Cosinus einmal mit Hilfe der Funktion aus \texttt{math.h} und einmal über die Reihenentwicklung, die wir zu einer in der Kommandozeile angegebenen Ordnung abbrechen:
\begin{lstlisting}[caption={Beispiel zur Verwendung des Cosinus}, belowcaptionskip=0.3em]
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
double winkel;
double coswinkel;
// genuegend Kommandozeilenparameter?
if (argc < 2) {
printf("Usage: ./print_cos Winkel Naeherungsordnung[optional]\n");
return(-1);
}
winkel = atof(argv[1]); // Konvertiert eine Zeichenkette in eine Fliesskommazahl
// cos aus math.h
printf("Winkel=%e \t cos(Winkel) = %e\n", winkel, cos(winkel));
// nun selbst, wenn die Naeherungsordnung gegeben wurde
if (argc > 2) {
double coswinkelapprox = 1.; // Das Ergebnis zu fuehrender Ordnung
double winkelsqr = winkel * winkel;
double partialsum = 1.; // Die Partialsummen
const int n = atoi(argv[2]); // atoi konvertiert eine Zeichenkette in eine ganze Zahl
coswinkelapprox = 1.;
int sign=1;
for (int i = 1; i < n; ++i) {
sign *= -1; // (-1)^l ist entweder 1 oder -1, wenn l gerade oder ungerade ist
partialsum *= winkelsqr / ((2 * i - 1) * 2 * i);
coswinkelapprox += sign * partialsum;
}
printf("cos(Winkel) approx %e\n", coswinkelapprox);
}
return(0);
}
\end{lstlisting}
Wenn auf der Kommandozeile die Ordnung der Näherung als zweiter Kommandozeilenparameter angegeben wurde\footnote{die Bedeutung von \texttt{argc} und \texttt{argv} wird in \cref{subsec:CommandLineArguments} erläutert}, berechnen wir auch die Näherung selbst nach der Formel Gleichung~\ref{eq:cos}.
Wie schon vorher erklärt, sind die Kommandozeilenparameter in der \texttt{main} Funktion nur als Zeichenkette verfügbar.
Die Konvertierung der Ordnung in eine ganze Zahl kann man mit der standard Funktion \texttt{atoi} (ASCII to integer) durchführen.
Genauso verwenden wir \texttt{atof} (ASCII to float) um den eingegebenen Winkel in the Fließkommazahl umzuwandeln.
Man beachte, dass die standard Cosinus Funktion das Argument im Bogenmaß erwartet.
Bei der Berechnung der Näherung müssen wir nicht in jedem Schritt die Potenz $x^{2i}$ und Fakultät $(2i)!$ neu berechnen, sonder müssen lediglich die Variablen \texttt{zaehler, nenner} entsprechend auffrischen.
Dies ist ein generelles Konzept: Man verwendet mehr Speicher um Rechnung zu sparen.
\subsubsection{Übersetzen und Linken mit \texttt{math.h}}
Das Programm kann man wie folgt übersetzen
\vspace*{0.5cm}
\begin{verbatim}
>$ gcc -std=c99 -Wall -pedantic cosineexample.c -o cos.exe -lm
\end{verbatim}
\vspace*{0.5cm}
\noindent Man beachte, dass man nun explizit die Bibliothek \texttt{math.h} dazulinken muss.
Dies geschieht mit dem Argument \texttt{-lm}.
In Tabelle~\ref{math} listen wir einige wichtige Funktionen auf, die \texttt{math.h} bereitstellt.
\subsection{Komplexe Zahlen mit \texttt{complex.h}}
Als zweite Standardbibliothek weisen wir noch auf \texttt{complex.h} hin.\index{\texttt{complex.h}}
Sie stellt einen komplexen Datentyp zur Verfügung, der leider nicht Teil von C selbst ist.
Die Benutzung ist dann aber gleich zu \texttt{C} Datentypen, wie man an folgendem Beispiel sieht:\index{\texttt{I}}\index{\texttt{complex}}\index{\texttt{cexp}}\index{Datentypen!\texttt{complex}}\index{Datentypen!\texttt{double complex}}
\begin{lstlisting}[caption={Beispiel für komplexe Zahlen}, belowcaptionskip=0.3em]
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main(int argc, char *argv[])
{
double complex z,v,w;
// I ist die rein komplexe Zahl i
z = 1 + I*3;
v = 0.3*I;
// komplexe Multiplikation
w = z*v;
// Zugriff auf Real- und Imaginaerteile
printf(``w = %e + i*%e\n'', creal(w), cimag(w));
// Anwendung der komplexen Exponetialfunktion
z = cexp(w);
printf(``w = %e + i*%e\n'', creal(z), cimag(z));
return 0;
}
\end{lstlisting}
\subsubsection{Mathematische Funktionen für komplexe Zahlen}
In \texttt{math.h} sind wiederum die Funktionen aus Tabelle~\ref{math} für den Typ \texttt{double complex} definiert.\index{\texttt{math.h}}
Meistens unterscheiden sie sich von den reellwertigen Funktionen nur duch ein vorgestelltes \texttt{'c'}, wie zum Beispiel bei \texttt{cexp}.\index{\texttt{cexp}}
Auf Real- und Imaginärteil kann mit \texttt{creal} und \texttt{cimag} zugegriffen werden.
\texttt{complex.h} stellt auch Typen \texttt{float complex} und \texttt{long double complex} bereit.
Die entsprechenden Exponentialfunktionen heißen dann \texttt{cexpf} und \texttt{cexpl}.
Das komplex konjugierte erhält man mit \texttt{conj}, bzw. \texttt{conjf} und \texttt{conjl}.
\index{\texttt{complex.h}}\index{\texttt{creal}}\index{\texttt{cimag}}\index{\texttt{conj}}
\begin{table}
\centering
% centering table
\begin{tabular}{|l l|}
\hline
\texttt{Deklaration} & \texttt{Rückgabewert} \\
% creating 10 columns
\hline
\texttt{double acos(double x);} & Arcuscosinus von \texttt{x}\\
\texttt{double asin(double x);} & Arcussinus von \texttt{x}\\
\texttt{double atan(double x);} & Arcustangenz von \texttt{x}\\
\texttt{double atan2(double y,double x);} & Arcustangenz von \texttt{x/y}\\
\texttt{double ceil(double x);} & Kleinste ganze Zahl, welche $\ge$ \texttt{x} ist \\
\texttt{double cos(double x);} & Cosinus von \texttt{x}\\
\texttt{double cosh(double x);} & Cosinus hyperbolicus von \texttt{x}\\
\texttt{double exp(double x);} & $e^{x}$ wobei $e=2.7182..$\\
\texttt{double fabs(double x);} & $\vert x\vert$\\
\texttt{double floor(double x);} & Größte ganze Zahl, welche $\le$ \texttt{x} ist \\
\texttt{double ldexp(double x, double y);} & $xe^{y}$ \\
\texttt{double log(double x);} & Natürlicher Logarithmus von \texttt{x}\\
\texttt{double log10(double x);} & Zehnerlogarithmus von \texttt{x}\\
\texttt{double pow(double x, double y);} & $x^{y}$\\
\texttt{double sin(double x);} & Sinus von \texttt{x}\\
\texttt{double sinh(double x);} & Sinus hyperbolicus von \texttt{x}\\
\texttt{double sqrt(double x);} & $\sqrt{x}$\\
\texttt{double tan(double x);} & Tangens von \texttt{x}\\
\texttt{double tanh(double x);} & Tangens hyperbolikus von \texttt{x}\\
\hline
\end{tabular}
\caption{Einige Funktionen, die in \texttt{math.h} deklariert sind.\label{math}}
\end{table}