Übungsabgabe

Hinweise zur 3. Übung

Initialisierung

Variablen müssen vor erstmaliger Verwendung oft initialisiert werden. Beispiel:

double sum;

[...]

sum = 0.0;
for (i=0; i<n; i++)
{
  sum += folge[i];
}

Je nach Compiler wird eine frisch angelegte Variable oft automatisch auf 0 gesetzt. Die (hier fettgedruckte) Initialisierung ist aber in diesem Praktikum verpflichtend (sonst Punkteabzug).

  1. kann man sich nicht auf die automatische Init verlassen,
  2. ist das nicht Initialisieren eine schlechte Angewohnheit die später zu oft unauffindbaren Fehlern führen kann,
  3. ist etwa bei dem obigen Beispiel sum = 0.0; einfach ein Bestandteil des Algorithmus. Deshalb wird sum auch an genau dieser Stelle (statt oben bei der Variablenvereinbarung) auf 0.0 gesetzt.

Vereinbarung von Feldern, Feldgrenzen

Wie setzt man mathematische Vektoren (und damit Matrizen) in C++-Felder um:

Vektor xi, i=1..10

  1. Möglichkeit (bevorzugt):

    const int N=10;
    double x[N];  // weil N Komponenten

    verwende x[0] bis x[9] für x1 bis x10 (d.h. index-shift)

  2. Möglichkeit:

    const int N=10;
    double x[N+1];

    verwende x[1] bis x[10] für x1 bis x10 (d.h. kein index-shift, 0-tes Element bleibt aber ungenutzt)

Vektor xi, i=0..10

Verbotene Feldzugriffe

Wird über ein Feld hinaus gelesen oder geschrieben

double x[10];
[...]
x[10] = 0.9;  // verbotener Schreibzugriff
[...]
cout << x[10]*x[10] - 2.0 << endl;  // verbotener Lesezugriff

kann alles Mögliche an Fehlern auftreten (keine Garantie).

pow, fabs

Wenn etwas nichts mit Potenzieren zu tun hat, ist die Verwendung von pow ineffizient. Auch fabs usw. nur verwenden wenn notwendig. Beispiele:

Falsch:

double x[N];
[...]
for (i=0; i<N; i++)
{
  x[i] = pow (-1.0, i+1.0) / (i+1.0);
}

Richtig:

double x[N];
double help;
[...]
help = -1.0;
for (i=0; i<N; i++)
{
  x[i] = help / (i+1.0);
  help = -help;
}

x = pow (fabs(y), 2);
x = fabs(y)*fabs(y);
x = y*y;   // Quadrate sind immer positiv!

Hilfsfelder nur wenn unbedingt notwendig

Viele haben bei der Berechnung der Matrixnormen (Übung 3, Bsp. 2) Hilfsfelder für die Spaltensummen etc. verwendet. Es gibt aber einen Algorithmus der ohne diese auskommt (siehe Musterlösung) - in so einem Fall soll man also auch auf die Hilfsfelder verzichten.

Vergleiche von Gleitkommavariablen

Gleitkommazahlen (double, float, etc.) soll man nie auf (Un)gleichheit testen. Falls erforderlich nur mit relativen Kriterium. Beispiel:

double x;
[...]
if (x == 0)   // richtig: if (fabs(x) < EPS)
{
[...]

Bei der 3. Übung, 1. Bsp, sollte der i-te Lagrange-Koeffizient berechnet werden. Hier ein logischer Fehler:

if (x[i] != x[j])   // richtig: if (i != j)