C++ Programmier-Aufgaben: Anwendungen aus Numerik, Finanzmathematik, Kombinatorik, Auszeichnungssprachen

Anwendungen aus verschiedensten Bereichen, in denen die bisher erlernten Konzepte von C++ eingesetzt werden können, werden als Programmier-Aufgaben formuliert.
Noch keine Stimmen abgegeben
Noch keine Kommentare

Einordnung des Artikels

In diesem Kapitel werden einige komplexere Anwendungen vorgestellt, die zeigen sollen, welche Aufgaben man mit den bisher erlernten elementaren Befehlen l√∂sen kann. Sie sollen sp√§ter im Sinne der strukturierten Programmierung √ľberarbeitet werden (siehe C++: Aufgaben zur strukturierten Programmierung).

Berechnung von Wurzeln

Der Taschenrechner berechnet die Wurzel einer Zahl a > 0 nach der Rekursionsformel aus Abbildung 1. Möchte man etwa die Wurzel aus 5 berechnen, so wird a = 5 gesetzt (und nicht mehr verändert) und die Rekursionsformel startet mit x1 = 5; sie läuft so lange, bis sich die Ergebnisse innerhalb der vom Taschenrechner angezeigten Stellen nicht mehr verändern.

Abbildung 1: Rekursionsformel zur näherungsweisen Berechnung der Wurzel.Abbildung 1: Rekursionsformel zur näherungsweisen Berechnung der Wurzel.

Aufgabe:

Wie genau kann man die Wurzel aus 5 mit C++ berechnen,

  • wenn man den Datentyp float verwendet,
  • wenn man den Datentyp double verwendet?

Wie oft wird dabei jeweils in die Rekursionsformel eingesetzt?

Vergleichen Sie Ihre Ergebnisse mit dem des Taschenrechners.

Wieviele Rechenschritte hat der Taschenrechner benötigt?

Finanzmathematik

Verzinsung

Wird ein Kapital K0 so angelegt, dass es j√§hrlich mit einem Zinssatz i verzinst wird und die Zinsen nicht ausgesch√ľttet werden (Zinseszins), so berechnet sich das Kapital Kn nach n Jahren durch:

Kn = K0 · (1 + i)n

(Achtung: Der Zinssatz i ist keine Prozentzahl)

Aufgabe:

Schreiben Sie ein Programm, bei dem K0, n, i eingegeben werden und der Kontostand nach j = 1, 2, ... , n Jahren ausgegeben wird.

Berechnen Sie im Vergleich dazu, wie gro√ü das Kapital K(j) bei Aussch√ľttung ist. (Damit ist gemeint: Das Kapital K0 bleibt auf der Bank liegen, die Zinsen werden j√§hrlich ausbezahlt und K (j) ist die Summe aus K0 und den nach j Jahren insgesamt ausbezahlten Zinsen.)

Tilgungsrechnung

Die beiden einfachsten Arten, wie ein Kredit zur√ľckbezahlt werden kann, sind:

  • Ratentilgung
  • Annuit√§tentilgung.

Bei der Ratentilgung wird eine j√§hrlich konstante Tilgung geleistet; zus√§tzlich m√ľssen f√ľr die noch bestehende Restschuld Zinsen bezahlt werden ‚ÄĒ dadurch ist der j√§hrlich zu bezahlende Gesamtbetrag (die Annuit√§t) nicht konstant.

Bei der Annuit√§tentilgung wird j√§hrlich ein konstanter Betrag zur√ľckbezahlt (dieser Betrag ist die Annuit√§t, die nat√ľrlich gr√∂√üer sein muss als die Zinsen auf den Kreditbetrag); wie sich die Annuit√§t aus Tilgung und Zinsen zusammensetzt, ist dann auf den ersten Blick nicht erkennbar.

Die Berechnungen f√ľr die Annuit√§tentilgung werden aber deutlich einfacher, wenn man die j√§hrliche Annuit√§t vorgibt (wobei man dann meist die Annahme trifft, dass die letzte Annuit√§t abweichen darf). Der Nachteil ist dann, dass man die Laufzeit erst angeben kann, wenn man den Tilgungsplan aufgestellt hat.

Die Ratentilgung ist leichter zu berechnen, die Annuit√§tentilgung wird in der Praxis h√§ufiger angewandt. In der Tabelle in Abbildung 2 ist f√ľr einen Kredit √ľber 100000 EUR der Tilgungsplan f√ľr den Fall der Annuit√§tentilgung dargestellt; dabei wird ein Zinssatz von 10 Prozent angenommen und der Kredit soll innerhalb von 4 Jahren zur√ľckbezahlt werden.

Abbildung 2: Tilgungsplan f√ľr einen Kredit mit Annuit√§tentilgung, der innerhalb von 4 Jahren zur√ľckbezahlt wird.Abbildung 2: Tilgungsplan f√ľr einen Kredit mit Annuit√§tentilgung, der innerhalb von 4 Jahren zur√ľckbezahlt wird.

Aufgabe:

Schreiben Sie ein Programm, mit dem f√ľr beliebigen Kreditbetrag K, beliebigen Zinssatz p (in Prozent) und f√ľr beliebige R√ľckzahlungsdauer n (in Jahren) der Tilgungsplan aufgestellt wird; und zwar einmal f√ľr Ratentilgung und einmal f√ľr Annuit√§tentilgung. Im Fall der Annuit√§tentilgung sollen zwei Varianten angeboten werden:

  • die Annuit√§t ist auch im letzten Jahr konstant (wie im Beispiel der Tabelle oben)
  • die letzte Annuit√§t (f√ľr das (n+1)-te Jahr) kann abweichen, soll aber kleiner sein als die Annuit√§t f√ľr die Jahre 1 bis n. Die Annuit√§t f√ľr die ersten n Jahre soll eine m√∂glichst glatte Zahl sein.

Rundungsfehler, die kleiner als ein Cent sind, können ignoriert werden.

Abzählprobleme

In der Kombinatorik werden Formeln hergeleitet, mit denen man bei vielen Zufalls-Experimenten abzählen kann, wieviele mögliche Ausgänge es gibt. Beispielsweise zeigt Abbildung 3 die Berechnung der Anzahl der Möglichkeiten beim Zahlenlotto 6 aus 49.

Abbildung 3: Anzahl der Möglichkeiten beim Zahlenlotto 6 aus 49.Abbildung 3: Anzahl der Möglichkeiten beim Zahlenlotto 6 aus 49.

Man kann die Formel leicht nachvollziehen:

  • F√ľr die erste gezogene Zahl gibt es 49 M√∂glichkeiten,
  • f√ľr die zweite gezogene Zahl bleiben noch 48 M√∂glichkeiten, ...
  • f√ľr die sechste gezogene Zahl noch 44 M√∂glichkeiten.
  • Da man die Reihenfolge, in der die Zahlen gezogen werden, nicht voraussagen muss, liefern 6! m√∂gliche Anordnungen der gezogenen Zahlen dasselbe Ergebnis der Ziehung.

Es lassen sich aber auch viele Probleme formulieren, f√ľr die eine entsprechende Formel nicht bekannt ist oder die so schwierig erscheinen, dass man nicht erwarten kann, in vern√ľnftiger Zeit die Formel zu finden.

Um ein nicht ganz einfaches Beispiel zu nennen:

Ein W√ľrfel wird viermal nacheinander geworfen und die vier Augenzahlen werden notiert.

  • Wieviele verschiedene Ergebnisse gibt es insgesamt bei diesem Experiment?
  • Bei wievielen Ergebnissen sind die Augenzahlen echt aufsteigend? (Die Folge 1246 ist echt aufsteigend, die Folge 1244 dagegen nicht.)

Die erste Frage ist noch leicht zu beantworten: Da der W√ľrfel sechs verschiedene Ergebnisse liefern kann und die unabh√§ngig voneinander kombiniert werden m√ľssen, gibt es insgesamt 64 = 1296 M√∂glichkeiten.

Die zweite Frage ist schon deutlich schwieriger: Wenn im ersten Wurf eine 1 erscheint, gibt es f√ľr den zweiten Wurf noch 5 M√∂glichkeiten; die Anzahl der M√∂glichkeiten beim dritten Wurf h√§ngt dann vom Ergebnis des zweiten Wurfes ab, ... Oder ist es einfacher, alle M√∂glichkeiten aufzuschreiben?

Hier kann ein Programm weiterhelfen: Man rechnet mit roher Gewalt (brute force) alle 64 = 1296 M√∂glichkeiten durch und entscheidet bei jeder M√∂glichkeit, ob die Bedingung echt aufsteigend erf√ľllt ist; man muss dann nur noch mitz√§hlen.

Aufgaben:

Schreiben Sie zu folgenden Abzählproblemen ein C++-Programm, das alle möglichen Ergebnisse erzeugt und die gesuchten Ereignisse abzählt.

1. Ein W√ľrfel wird viermal nacheinander geworfen und die vier Augenzahlen werden notiert.

  • Wieviele verschiedene Ergebnisse gibt es insgesamt bei diesem Experiment?
  • Bei wievielen Ergebnissen sind die Augenzahlen echt aufsteigend? (Die Folge 1246 ist echt aufsteigend, die Folge 1244 dagegen nicht.)
  • Bei wievielen Ergebnissen sind die Augenzahlen aufsteigend? (Die Folge 1244 ist aufsteigend, die Folge 1243 dagegen nicht.)

2. Ein W√ľrfel wird sechsmal nacheinander geworfen und die sechs Augenzahlen werden notiert.

Wieviele Möglichkeiten gibt es, so dass mindestens zweimal nacheinander (egal wann) eine 6 erscheint?

Durch Abzählen erhält man hier:

1 · 1 · 6 · 6 · 6 · 6 = 1296 (6 im ersten Wurf, 6 im zweiten Wurf, beliebige Zahl im dritten Wurf,...)

5 · 1 · 1 · 6 · 6 · 6 = 1080 (keine 6 im ersten Wurf, 6 im zweiten Wurf, 6 im dritten Wurf, beliebige Zahl im vierten Wurf,...)

5 · 5 · 1 · 1 · 6 · 6 = 900

5 · 5 · 5 · 1 · 1 · 6 = 750

5 · 5 · 5 · 5 · 1 · 1 = 625

Es sind also insgesamt 4651 Möglichkeiten.

3. Jäger und Hasen:

Die folgende Abbildung 4 zeige j Jäger und h Hasen (im Spezialfall j = 4 = h), wobei gelten soll:

  • jeder J√§ger zielt auf einen Hasen,
  • kein J√§ger wei√ü, auf welchen Hasen die anderen J√§ger zielen,
  • alle J√§ger schie√üen einmal und gleichzeitig,
  • jeder J√§ger trifft.

Abbildung 4: Vier Jäger zielen auf vier Hasen. Dargestellt ist eine mögliche Realisierung.Abbildung 4: Vier Jäger zielen auf vier Hasen. Dargestellt ist eine mögliche Realisierung.

Durch ein C++-Programm ist herauszufinden:

  • Wieviele m√∂gliche Realisierungen gibt es bei diesem Szenario insgesamt (f√ľr j = 4 = h)?
  • Bei wievielen M√∂glichkeiten √ľberleben null, ein, zwei beziehungsweise drei Hasen?
  • Wie gro√ü ist der Erwartungswert der Anzahl der √ľberlebenden Hasen?
  • Wie kann man das Programm verallgemeinern, so dass obige Fragen f√ľr beliebiges j und h beantwortet werden k√∂nnen?

Arbeiten mit Auszeichnungssprachen

Dieser Abschnitt schlie√üt insbesondere an das Kapitel Auszeichnungssprachen (markup language) an: jetzt werden konkrete Aufgaben gestellt, die zeigen sollen, wie man Auszeichnungssprachen in der Praxis einsetzen kann. Oftmals werden Texte, die in einer Auszeichnungssprache vorliegen, gegen√ľber reinem Text als lediglich aufgebl√§ht wahrgenommen, da der eigentliche Inhalt des Textes schwer herauszuarbeiten ist. In den Beispielen hier soll gezeigt werden, dass die Textverarbeitung durch die Verwendung von Auszeichnungssprachen aber deutlich erleichtert wird, da man gezielt auf Inhalte zugreifen kann beziehungsweise gegebene Inhalte besser aufbereiten kann.

Erzeugen von HTML-Tabellen

Der Quelltext einer HTML-Seite, die eine Überschrift und eine Tabelle enthält, könnte folgendermaßen aussehen:

<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
	table {border-collapse: collapse;}
	th, td {border: 1px solid #ddd; padding: 5px;}
</style>
<title="Liste von Quadratzahlen">
</head>
<body>
<h1>Quadratzahlen</h1>

<table>
	<tr>
		<th>n</th><th>n<sup>2</sup></th>
	</tr>
	<tr>
		<td>1</td><td>1</td>
	</tr>
	<tr>
		<td>2</td><td>4</td>
	</tr>
	<tr>
		<td>3</td><td>9</td>
	</tr>
	<tr>
		<td>4</td><td>16</td>
	</tr>
	<tr>
		<td>5</td><td>25</td>
	</tr>
	<tr>
		<td>6</td><td>36</td>
	</tr>
</table>

</body>

Die eigentlichen Inhalte der Tabelle befinden sich innerhalb des Elementes <table> ; die Darstellung der Tabelle wird durch die Anweisungen in <style> festgelegt (jede Zelle der Tabelle ist von einem Rahmen der Dicke 1 px mit hellgrauer Farbe umgeben; die Inhalte der Zellen haben in jeder Richtung vom Rahmen einen Abstand von 5 px).

Die Tabelle besteht aus zwei Spalten und insgesamt 7 Zeilen; davon ist die erste Zeile eine Kopfzeile (mit fett-gedruckten √úberschriften) und 6 Zeilen mit den eigentlichen Tabellen-Inhalten. Dieser Quelltext erzeugt folgende Tabelle:

n n2
1 1
2 4
3 9
4 16
5 25
6 36

Die hier dargestellte Tabelle sollte mit derjenigen identisch sein, die Sie sehen, wenn Sie obigen Quelltext in einer .html-Datei abspeichern und mit dem Web-Browser öffnen. Der Grund liegt darin, dass die style-Information, die oben im Kopf der html-Datei definiert sind, ebenfalls in der .css-Datei der aktuellen Seite definiert sind:

<style>
	table {border-collapse: collapse;}
	th, td {border: 1px solid #ddd; padding: 5px;}
</style>

Um den Quelltext der Tabelle zu verstehen, muss man nur die entsprechenden html-Elemente kennen, sie sind in der folgenden Tabelle kurz erklärt:

Element Abk√ľrzung f√ľr (oder √úbersetzung) Bedeutung
table Tabelle Erzeugt eine html-Tabelle
tr table row = Tabellenzeile Zeile in einer Tabelle; muss dem Element table untergeordnet sein.
th table header = Tabellenkopf Kopfzelle einer Tabelle; muss dem Element tr untergeordnet sein. Anzahl pro Zeile: siehe td.
td table data = Tabellendaten Datenzelle; muss dem Element tr untergeordnet sein. Die Anzahl der Zellen pro Zeile sollte identisch sein (andernfalls muss man weitere Befehle einsetzen).

Aufgaben:

1. Schreiben Sie ein C++-Programm, das den einfachen Inhalt der Tabelle der Quadratzahlen als Konsolen-Ausgabe erzeugt. Mit einfachem Inhalt ist gemeint, dass nur die Tabellen-Zeilen erzeugt werden, also die Zeilen 13 bis 35 aus dem Quelltext oben.

2. Schreiben Sie ein C++-Programm, mit dem die Zahlen von 0 bis 255 in einer zwei-spaltigen html-Tabelle ausgegeben werden: In der ersten Spalte als Dezimalzahl, in der zweiten Spalte als Hexadezimalzahl.

Versuchen Sie das Programm so zu erweitern, dass in einer dritten Spalte die zugehörige Dualzahl ausgegeben wird.

Mit Ausgabe ist nat√ľrlich wieder gemeint, dass die entsprechende Konsolen-Ausgabe erzeugt wird. Wenn Sie diese Ausgabe in die html-Datei kopieren (anstelle von Zeile 13 bis 35), k√∂nnen Sie diese Tabelle mit dem Web-Browser ansehen.

3. Die folgende Tabelle zeigt einige pythagoreische Zahlen-Tripel, also Zahlen mit a2 + b2 = c2:

a b c
3 4 5
5 12 13
8 15 17
7 24 25
20 21 29
12 35 37
9 40 41
28 45 53
11 60 61
33 56 65
16 63 65
48 55 73
36 77 85
13 84 85
39 80 89
65 72 97
20 99 101
60 91 109
15 112 113
44 117 125
88 105 137
24 143 145
17 144 145
51 140 149
85 132 157
119 120 169
52 165 173
19 180 181
104 153 185
57 176 185
95 168 193
28 195 197

Formulieren Sie:

  • Welche pythagoreischen Zahlen-Tripel sind in der Tabelle dargestellt, welche fehlen?
  • Wie sind die Zahlen-Tripel angeordnet?

Schreiben Sie ein C++-Programm, das diese Zahlen-Tripel berechnet und die HTML-Tabelle erzeugt!

4. Wie kann man die logische Funktion XOR auf die elementaren Funktionen AND, OR und NOT zur√ľckf√ľhren?

Schreiben Sie ein Programm, das die Tabelle (nicht die Schaltzeichen) der folgenden Abbildung als html-Tabelle erzeugt.

Abbildung 5: Logik-Tabelle und Schaltzeichen f√ľr die wichtigsten Booleschen Funktionen.Abbildung 5: Logik-Tabelle und Schaltzeichen f√ľr die wichtigsten Booleschen Funktionen.

So wie hier die html-Dateien mit Inhalten gef√ľllt werden, ist noch viel zu viel Handarbeit n√∂tig (Konsolen-Ausgabe in Dateien kopieren und so weiter). Mit den Funktionen der Standard-Bibliothek zum Lesen und Schreiben von Dateien, kann man auch die Handarbeit automatisieren:

  • Man bereitet sich eine Datei header.html vor (etwa Zeile 1 bis 11 mit kleinen Anpassungen aus dem Quelltext oben).
  • Ebenso eine Datei footer.html (Zeile 36 bis 37).
  • Um die neue html-Datei aus der Konsolen-Ausgabe zu erzeugen, wird:
    1. eine neue (leere) Datei angelegt, etwa squares.html,
    2. der Inhalt von header.html in squares.html geschrieben,
    3. die Konsolen-Ausgabe nach squares.html umgeleitet,
    4. die Datei footer.html in squares.html geschrieben,
    5. die Datei squares.html geschlossen.

Sie k√∂nnen sich ein wenig in der C++-Dokumentation umsehen (Input/output library), ob Sie die entsprechenden Funktionen finden! Und es gibt nat√ľrlich zahlreiche Verbesserungen der hier vorgestellten Methode, um Ausgaben zu automatisieren.

Erzeugen von Vektorgraphiken

Skalierbare Vektorgraphiken (scalable vector graphics) können besonders leicht in html-Dateien eingebunden werden:

Zum Einen können sie wie andere Bilder (im Dateiformat .jpg oder .png) mit Hilfe des img-Elementes aufgerufen werden; der Quelltext dazu sieht dann etwa so aus:

<img src="img/graphik.svg" alt="Abbildung" width="1200" height="900">

Das Attribut src beschreibt den Pfad zur Datei graphik.svg.

Zum anderen können Vektorgraphiken direkt im Quelltext erstellt werden; dies ist ohne Verwendung des img-Elementes möglich. Dazu muss man wissen, dass skalierbare Vektorgraphiken eigentlich Textdateien sind; genauer sind es xml-Dateien (xml = extensible markup language), deren Elemente vom Browser als graphische Elemente interpretiert werden.

Darstellung zweidimensionaler Funktionen

Beispiel:

Der folgende Quelltext (in den body eines html-Quelltextes kopiert) erzeugt zwei Rechtecke und einen Kreis, die mit Farbe gef√ľllt sind:

<svg width="600" height="400">
	<rect width="400" height="200" style="fill:rgb(0,0,255);stroke-width:5;stroke:rgb(0,0,0)" />
	<rect x="400" y="0" width="50" height="300" stroke="gray" stroke-width="4" fill="rgb(255,128,0)" />
	<circle cx="100" cy="100" r="50" stroke="red" stroke-width="2" fill="yellow" />
</svg>

Werden diese Zeilen in den html-Quelltext eingebunden, wird in der html-Seite folgendes Bild dargestellt:

Abbildung 6: Testbild zur Erklärung (im Text unten) der Elemente in einer .svg-Datei.Abbildung 6: Testbild zur Erklärung (im Text unten) der Elemente in einer .svg-Datei.

Zur Erklärung:

  1. Durch die Attribute width und height im Element svg wird ein Koordinatensystem definiert, dessen Ursprung ist links oben; die x-Achse zeigt nach rechts, die y-Achse nach unten (Zeile 1).
  2. An der Definition der Rechtecke (Zeile 2 und 3) und des Kreises (Zeile 4) kann man dies leicht nachvollziehen.
  3. Das erste Rechteck besitzt keine absolute Ortsangabe sondern nur Breite und Höhe: es wird vom Ursprung aus mit diesen Angaben gezeichnet.
  4. F√ľr das zweite Rechteck sind x- und y-Koordinate definiert, sie beschreiben den linken oberen Eckpunkt.
  5. Die Lage des Kreises erkl√§rt sich von selbst. Da der Kreis im Quelltext nach dem Rechteck kommt, wird der Kreis √ľber das Rechteck gezeichnet.
  6. Die Attribute, die die Farben des Rahmens (stroke) und der F√ľllung (fill) beschreiben, k√∂nnen mit style-Angaben definiert werden (Zeile 2) oder mit den Einzel-Attributen (Zeile 3 und 4).
  7. Farben k√∂nnen entweder mit Schl√ľsselworten (f√ľr vordefinierte Farben) oder im rgb-Modus (rot, gr√ľn, blau) angegeben werden. Im rgb-Modus werden die drei Farb-Komponenten mit ganzen Zahlen von 0 bis 255 angegeben. Die Angabe rgb(0,0,255) steht somit f√ľr blau.

Aufgaben:

1. Machen Sie eine kurze Kurvendiskussion (Nullstellen, Wertebereich, Verhalten am Rand des Definitionsbereiches) der Funktion

f(x,y) = x2 - y2, D = [ -1; +1 ] √ó [ -1; +1 ]

2. Der Definitionsbereich soll in Quadrate zerlegt werden. Der Funktionswert soll in eine geeignete Farbe √ľbersetzt werden (etwa rot f√ľr positive Werte, blau f√ľr negative Wert, wei√ü f√ľr null). √úberlegen Sie wie man ein Programm aufbauen kann, das die Funktionswerte √ľber dem Definitionsbereich durch Farben sichtbar macht.

3. Eine mögliche Realisierung ist unten gezeigt (Abbildung 7). Wenn Sie Abbildung 7 abspeichern und mit einem Text-Editor öffnen, können Sie den Quelltext lesen. Er ist zwar sehr lang, aber seine Systematik sollte schnell erkennbar sein.

4. Darunter ist das C++-Programm, mit dem die Graphik erzeugt wurde (wie oben beschrieben, indem die Konsolen-Ausgabe in die html-Datei kopiert wurde). Das Programm ist im Sinne der strukturierten Programmierung geschrieben; versuchen Sie dennoch, das Programm zu verstehen.

Abbildung 7: Graphische Darstellung der Funktion f(x,y)  im oben angegebenen Definitionsbereich, indem die Funktionswerte in Farben √ľbersetzt wurden.Abbildung 7: Graphische Darstellung der Funktion f(x,y) im oben angegebenen Definitionsbereich, indem die Funktionswerte in Farben √ľbersetzt wurden.

Das Bild wurde mit Hilfe des folgenden Quelltextes erzeugt:

/* Programm zur Darstellung einer zweidimensionalen Funktion:
    die Funktionswerte √ľber dem Definitionsbereich werden in Farben √ľbersetzt
	Der Definitionsbereich wird durch 200 x 200 Pixel dargetellt, ein Quadrat im svg hat 8 x 8 Pixel
	200 = 8 x 25: zur Verallgemeinerung m√ľsste man f√ľr 200, 8, 25 Variablen einf√ľhren.
*/

#include <iostream>

using namespace std;

// Breite und Höhe des Bildes: 200 Pixel, Auflösung zur Darstellung: 8 Pixel
const int WIDTH = 8;        // Breite des Rechtecks
const int HEIGHT = 8;       // Höhe des Rechtecks

/* f: Funktion, deren H√∂he √ľber dem Definitionsbereich farbig dargetellt werden soll
Achtung: der Def.bereich ist [-1;+1] x[-1;+1] und die Funktionswerte m√ľssen in [-1;+1] liegen
(andernfalls liefern die 3 Funktionen f√ľr die Farben keine g√ľltigen Werte
-> Funktion skalieren, falls Wertebereich nicht in [-1;+1]
*/
double f(double x, double y);

/* erzeugt svg-Quelltext f√ľr Rechteck mit Koordinaten x ,y (in Pixel) und rgb-Farbe, also r, g, b = 0,.., 255 */
void printRectangular(int x, int y, int r, int g, int b);

/* Funktionen, die den rgb-Anteil der Farbe in Abhängigkeit vom Funktionswert z in [-1; +1] berechnen */
int red(double z);
int green (double z);
int blue(double z);

/* löst Ausgabe aus, wird in main() aufgerufen */
void printSvg();

int main()
{
    printSvg();
    return 0;
}

double f(double x, double y){
    return x * x - y * y;
}

/* alternative Funktionen
double f(double x, double y){
    return 0.5 * (x * x + y * y);
}

double f(double x, double y){
    return  (x * x + y * y - 1);
}
*/

void printRectangular(int x, int y, int r, int g, int b){

    // <rect x="400" y="0" width="50" height="300" fill="rgb(255,128,0)" />
    cout << "<rect x = \"" << x << "\" y = \"" << y << "\" width=\"" << WIDTH <<
            "\" height=\"" << HEIGHT << "\" fill=\"rgb(" << r << "," << g << "," << b << "\)" />" << endl;
}

int red (double z){
    if (z < 0)
        return 0;
    return 255;
}

int green (double z){
    if (z < 0)
         z *= -1;
    int green = (1 - z) * 255;
    return green;
}

int blue (double z){
    if (z > 0)
        return 0;
    return 255;
}

void printSvg(){
    int x;      // Position in Pixel
    int y;      // Position in Pixel

    double x_D;     // Position im Definitionsbereich
    double y_D;     // Position im Definitionsbereich
    double z;           // Funktionswert bei (x_D, y_D), z = f(x,y) = x^2 - y^2

    for (int i = 1; i < 26; i++){      // x-Richtung
        for (int k = 1; k < 26; k++){      // y-Richtung
            x = 8 * i;
            y = 8 * k;
            x_D = static_cast<double> (8 * i) / 100 - 1;
            y_D = 1 - static_cast<double> (8 * k) / 100;
            z = f(x_D, y_D);
            printRectangular(x, y, red(z), green(z), blue(z));
        }
    }

Weitere Beispiele:

1. Darstellung der Funktion

g(x,y) = (x2 + y2) / 2, D = [ -1; +1 ] √ó [ -1; +1 ]

Abbildung 8: Graphische Darstellung der Funktion g(x,y) im oben angegebenen Definitionsbereich; wie im Beispiel oben werden die Funktionswerte in Farben √ľbersetzt.Abbildung 8: Graphische Darstellung der Funktion g(x,y) im oben angegebenen Definitionsbereich; wie im Beispiel oben werden die Funktionswerte in Farben √ľbersetzt.

2. Darstellung der Funktion

h(x,y) = x2 + y2 - 1, D = [ -1; +1 ] √ó [ -1; +1 ]

Abbildung 9: Graphische Darstellung der Funktion h(x,y) im oben angegebenen Definitionsbereich; wieder werden die Funktionswerte in Farben √ľbersetzt.Abbildung 9: Graphische Darstellung der Funktion h(x,y) im oben angegebenen Definitionsbereich; wieder werden die Funktionswerte in Farben √ľbersetzt.

Wurfparabeln

Die folgende Abbildung 10 zeigt drei Kugeln, die aus identischer Anfangsposition und betragsgleicher Anfangsgeschwindigkeit unter verschiedenen Winkeln abgeworfen werden; die Winkel betragen 30¬į, 45¬į, 60¬į. Dargestellt sind 50 Stroboskopaufnahmen zu 50 verschiedenen Zeitpunkten (in identischem Zeitabstand).

Abbildung 10: Stroboskopaufnahmen beim schiefen Wurf mit unterschiedlichen Abwurfwinkeln.Abbildung 10: Stroboskopaufnahmen beim schiefen Wurf mit unterschiedlichen Abwurfwinkeln.

In der Abbildung 11 sind sie als Animation gezeigt (zus√§tzlich eine vierte Wurfparabel zum Anfangswinkel 75¬į).

Abbildung 11: Wurfparabeln als Animation.Abbildung 11: Wurfparabeln als Animation.

Möglich gemacht werden Animationen in Vektorgraphiken durch das Element <animateMotion> , das hier nicht erklärt werden soll.

Aufgabe:

Schreiben Sie ein Programm, das mit den oben vorgestellten Methoden die Stroboskop-Aufnahmen der Wurfparabeln als svg-Graphik zeigt.

Informieren Sie sich, wie das Element <animateMotion> eingesetzt wird und schreiben Sie ein Programm, das die Wurfparabeln als Animation zeigt.

Pythagoreische Zahlen-Tripel

Weiter oben unter Erzeugen von HTML-Tabellen wurde eine Tabelle mit speziellen pythagoreischen Zahlen-Tripeln gezeigt; f√ľr die Tabelle wurde c < 200 gew√§hlt.

Eine graphische Darstellung der entsprechenden pythagoreischen Zahlen-Tripel mit c < 1000 zeigt Abbildung 12.

Abbildung 12: Pythagoreische Zahlen-Tripel mit c &lt; 1000.Abbildung 12: Pythagoreische Zahlen-Tripel mit c < 1000.

Aufgabe:

Schreiben Sie ein C++-Programm, das die Zahlen-Tripel f√ľr Abbildung 12 berechnet und den Quelltext f√ľr die Vektorgraphik erzeugt.

Simulation von Schaltungen

Im Kapitel Die Komponenten des von Neumann Rechners wurden mehrere Schaltnetze und Schaltwerke besprochen. Da die Sprache C++ die logischen Operationen NOT, AND, OR bereitstellt und alle anderen logischen Operationen daraus aufgebaut werden können, ist es möglich Schaltungen in Programmen zu simulieren. Die Möglichkeit Schleifen zu bilden, erlaubt dann sämtliche Eingabewerte (bei Schaltnetzen) und zusätzlich sämtliche Speicherzustände (bei Schaltwerken) durchzuspielen.

Aufgaben:

1. Auslösen von Warnsignalen:

4 Temperaturmessf√ľhler sollen nach bestimmten Regeln einen Alarm ausl√∂sen k√∂nnen; Dazu wird f√ľr jeden F√ľhler ein Schwellenwert festgelegt. √úber zwei Steuerleitungen (s1 s0) k√∂nnen die Zahlen 0, 1, 2, 3 als Dualzahl √ľbertragen werden. Das durch die Steuerleitungen √ľbertragene Signal legt die Regeln fest, wann ein Alarm ausgel√∂st wird:

  • Zeigen die Steuerleitungen 00, wird kein Alarm ausgel√∂st (egal, was die Temperaturf√ľhler anzeigen).
  • Zeigen die Steuerleitungen 1, 2 beziehungsweise 3 (als Dualzahl) wird Alarm ausgel√∂st, wenn 1, 2 beziehungsweise 3 Temperaturf√ľhler den Schwellenwert √ľberschreiten.

Geben Sie hierf√ľr die logische Tabelle und die Realisierung als Schaltung an!

Schreiben Sie ein C++-Programm, das die Schaltung simuliert!

2. Flip-Flop mit NOT und NAND:

Abbildung 13 zeigt eine andere Realisierung des Flip-Flop als im Kapitel Die Komponenten des von Neumann Rechners: elektrotechnische Grundlagen besprochen wurde.

  • Analysieren Sie dieses Flip-Flop nach der dort vorgestellten Methode. Untersuchen Sie insbesondere ob es instabile und inkonsistente Zust√§nde gibt.
  • Falls es instabile und inkonsistente Zust√§nde gibt, nehmen Sie an, dass S gegen√ľber R dominiert (also S = 1 und R = 1 wird wie S = 1 und R = 0 behandelt).
  • Geben Sie die Tabelle an, die alle Eingabewerte und m√∂glichen Speicherzust√§nde durchspielt.
  • Schreiben Sie ein C++-Programm, das die Tabelle erzeugt.

Abbildung 13: Flip-Flop, das mit NOT und NAND realisiert ist.Abbildung 13: Flip-Flop, das mit NOT und NAND realisiert ist.