add ipi4
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,120 @@
|
||||
\documentclass[uebung]{../../../lecture}
|
||||
|
||||
\usepackage{listings}
|
||||
\usepackage{enumerate}
|
||||
\usepackage{array}
|
||||
|
||||
\lstset{
|
||||
frame=tb,
|
||||
tabsize=4
|
||||
}
|
||||
|
||||
\title{Übungsblatt Nr. 4}
|
||||
\author{Samuel Weidemeier, Christian Merten}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{tabular}{|c|m{1cm}|m{1cm}|m{1cm}|m{1cm}|m{1cm}|@{}m{0cm}@{}}
|
||||
\hline
|
||||
Aufgabe & \centering A1 & \centering A2 & \centering A3 & \centering A4 & \centering $\sum$ & \\[5mm] \hline
|
||||
Punkte & & & & & & \\[5mm] \hline
|
||||
\end{tabular}
|
||||
|
||||
\begin{aufgabe}
|
||||
Zahlendarstellung
|
||||
|
||||
\begin{enumerate}[a)]
|
||||
\item Berechnung der Determinante einer $2\times 2 $ Matrix.
|
||||
\begin{lstlisting}[language=C++, title=Berechnung der Determinante, captionpos=b]
|
||||
double determinante_double(double a, double b, double c, double d) {
|
||||
return a*d - b*c;
|
||||
}
|
||||
|
||||
float determinante(float a, float b, float c, float d) {
|
||||
return a*d - b*c;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Das Ergebnis bei Verwendung von \verb+float+ ist $10000$ und damit nicht exakt.
|
||||
Das liegt an der zu geringen Größe eines \verb+float+'s, der nur rund $7$ Dezimalstellen exakt
|
||||
speichern kann, danach wird gerundet. Das führt in diesem Fall zum Verlust aller
|
||||
Nachkommastellen. Bei Verwendung des Datentyps \verb+double+ reichen die rund $16$ Stellen aus, um
|
||||
das Ergebnis exakt darzustellen.
|
||||
\item Assoziativität bei \verb+float+s
|
||||
\begin{lstlisting}[language=C++, title=Vergleich der zwei Versionen, captionpos=b]
|
||||
float testAssoziativitaet() {
|
||||
for (int n = 6; n <= 14; n++) {
|
||||
// (a+b)+c
|
||||
float vers1 = (pow(10, n) + pow(-10, n)) + pow(10,-n);
|
||||
// a+(b+c)
|
||||
float vers2 = pow(10, n) + (pow(-10, n) + pow(10,-n));
|
||||
print(n, vers1, vers2, 0);
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Das Ergebnis ist bereits ab $n = 5$ nicht mehr assoziativ. Das liegt daran, dass
|
||||
bei $(a+b)+c$ zunächst $10^{n} - 10^{n}$ berechnet wird, das aber immer null ist und danach
|
||||
einfach $10^{-n}$ ausgewertet wird. Dabei kann die gesamte Präzision des \verb+float+'s
|
||||
für die Nachkommastellen von $10^{-n}$ verwendet werden. Bei $a + (b+c)$ wird erst
|
||||
$-10^{n} + 10^{-n}$ berechnet. Hierbei reicht die Präzision nicht aus, um die Nachkommastellen
|
||||
darzustellen, da jetzt die Zahl bereits vor dem Komma sehr groß ist. Dadurch wird
|
||||
$-10^{n} + 10^{-n}$ auf $-10^{n}$ gerundet und dann mit $10^{n}$ addiert, was dann null ergibt.
|
||||
\end{enumerate}
|
||||
\end{aufgabe}
|
||||
|
||||
\begin{aufgabe} Effektiver Zinssatz
|
||||
|
||||
Programm siehe \verb+uebung4.cpp+
|
||||
|
||||
Die Ergebnisse erleiden durch Runden und den begrenzten Speicherplatz des \verb+float+'s einige
|
||||
Ungenauigkeiten. Die Differenz zum Grenzwert wird wie erwartet immer geringer.
|
||||
|
||||
Die Genauigkeit der \verb+double+ Werte ist höher.
|
||||
\end{aufgabe}
|
||||
|
||||
\begin{aufgabe} Multiplikation im Zweierkomplement
|
||||
|
||||
Zeigen Sie, dass für $n \in \N$ mit
|
||||
\[
|
||||
a, b, a \cdot b \in \left[ -2^{n-1}, 2^{n-1}- 1 \right]
|
||||
.\] für die Multiplikation im Zweierkomplement folgendes gilt:
|
||||
\[
|
||||
d_n(a\cdot b) = s_n(d_n(a)\cdot d_n(b))
|
||||
.\]
|
||||
|
||||
\begin{proof}
|
||||
Seien $a, b \in \left[ -2^{n-1}, 2^{n-1}-1 \right] $ mit $-2^{n-1} \le a\cdot b \le 2^{n-1}-1$ beliebig.
|
||||
|
||||
Fallunterscheidung:
|
||||
\begin{enumerate}[(i)]
|
||||
\item $a, b \ge 0$. Dann ist $a \cdot b \ge 0$. Damit
|
||||
\[
|
||||
s_n(d_n(a)\cdot d_n(b)) = s_n(a\cdot b) = a\cdot b = d_n(a\cdot b)
|
||||
.\]
|
||||
\item $a < 0, b > 0$ (analog $a > 0, b <0)$. Dann ist $a \cdot b < 0$.
|
||||
\begin{align*}
|
||||
s_n(d_n(a)\cdot d_n(b)) &= s_n((2^{n} - |a|) \cdot b) \\
|
||||
&= s_n((2^{n} + a) \cdot b) \\
|
||||
&= s_n(2^{n} \cdot b + a\cdot b) \\
|
||||
&= s_n(2^{n} \cdot b - |a+b|) \\
|
||||
&= 2^{n} - |a+b| \\
|
||||
&= d_n(a\cdot b)
|
||||
.\end{align*}
|
||||
\item $a < 0, b < 0$. Dann ist $a \cdot b > 0$.
|
||||
\begin{align*}
|
||||
s_n(d_n(a)\cdot d_n(b)) &= s_n((2^{n} - |a|)(2^{n} - |b|) \\
|
||||
&= s_n((2^{n} \cdot 2^{n} + 2^{n} \cdot b + a\cdot 2^{n} + a\cdot b) \\
|
||||
&= a \cdot b \\
|
||||
&= d_n(a\cdot b)
|
||||
.\end{align*}
|
||||
\item $a < 0, b = 0$ (analog $a = 0, b < 0$). Dann ist $a \cdot b = 0$.
|
||||
\begin{align*}
|
||||
s_n(d_n(a) \cdot d_n(b)) = s_n(\left( 2^{n} - |a| \right) \cdot 0) = s_n(0) = 0 = d_n(0) = d_n(a\cdot b)
|
||||
.\end{align*}
|
||||
\end{enumerate}
|
||||
\end{proof}
|
||||
|
||||
\end{aufgabe}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "cpp_headers/fcpp.hh"
|
||||
|
||||
// Berechne die Determinante einer 2x2 Matrix mit doubles
|
||||
double determinante_double(double a, double b, double c, double d) {
|
||||
return a*d - b*c;
|
||||
}
|
||||
|
||||
// Berechne die Determinante einer 2x2 Matrix mit floats
|
||||
float determinante(float a, float b, float c, float d) {
|
||||
return a*d - b*c;
|
||||
}
|
||||
|
||||
// Teste die Assoziativitaet von floating point Zahlen
|
||||
float testAssoziativitaet() {
|
||||
for (int n = 1; n <= 14; n++) {
|
||||
// (a+b)+c
|
||||
float vers1 = (pow(10, n) + -pow(10, n)) + pow(10,-n);
|
||||
// a+(b+c)
|
||||
float vers2 = pow(10, n) + (-pow(10, n) + pow(10,-n));
|
||||
print(n, vers1, vers2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Berechnet den effektiven Zinssatz mit floats
|
||||
// z: Zinssatz, n: Abrechnungsvorgaenge
|
||||
float zins(float z, int n) {
|
||||
return pow(1 + z/n, n) - 1;
|
||||
}
|
||||
|
||||
// Berechnet den effektiven Zinssatz mit doubles
|
||||
// z: Zinssatz, n: Abrechnungsvorgaenge
|
||||
double zins(double z, int n) {
|
||||
return pow(1 + z/n, n) - 1;
|
||||
}
|
||||
|
||||
// Vergleiche die Berechnung des effektiven Zinssatzes bei n Abrechnungsvorgaengen
|
||||
// mit floats und doubles und vergleiche mit dem Grenzwert für n -> unendlich.
|
||||
void compare(int n) {
|
||||
// Berechne effektiven Zins mit float
|
||||
float zf = zins(0.06, n);
|
||||
// Berechne die Differenz zu exp(z) - 1
|
||||
float difff = exp(0.06) - 1 - zf;
|
||||
// Berechne effektiven Zins mit double
|
||||
double zd = zins(0.06, n);
|
||||
// Berechne die Differenz zu exp(z) - 1
|
||||
double diffd = exp(0.06) - 1 - zd;
|
||||
// Gebe alles aus
|
||||
print("Abrechnungsvorgaenge:", n, 0);
|
||||
print("Zinssatz (float):", zf, 0);
|
||||
print("Abweichung von exp(z) - 1:", difff, 0);
|
||||
print("Zinssatz (double):", zd, 0);
|
||||
print("Abweichung von exp(z) - 1:", diffd, 0);
|
||||
print("");
|
||||
}
|
||||
|
||||
int main() {
|
||||
print("det", determinante(100, 0.01, -0.01, 100), 0);
|
||||
print("double det", determinante_double(100, 0.01, -0.01, 100), 0);
|
||||
testAssoziativitaet();
|
||||
|
||||
// vergleiche fuer verschiedene Werte
|
||||
compare(1);
|
||||
compare(4);
|
||||
compare(12);
|
||||
compare(365);
|
||||
compare(365*24);
|
||||
compare(365*24*60);
|
||||
compare(365*24*60*2);
|
||||
compare(365*24*60*60);
|
||||
}
|
||||
Reference in New Issue
Block a user