Autorensysteme - eExMx
Tutorial 4 - Übungen und Aufgaben mit Gleitkommazahlen programmieren
Anmerkung: Bevor Sie dieses Tutorial durchgehen, sollten Sie die ersten drei Tutorials gelesen haben. Hier werden die Programmfunktionen aus den Vorgängerlektionen nicht erneut erklärt.
In diesem Tutorial werden wir eine Mathematikübung mit Gleitkommazahlen programmieren und auf die Besonderheiten eingehen, die dabei zu berücksichtigen sind.
Auch bei dieser Übung gehen wir davon aus, dass die Kopfdaten für eine neue Übung bereits erfasst sind und nur noch die Übung zu programmieren ist. Dafür schalten wir über die eExMx-Toolleiste um auf Aufgabe.
Vorüberlegungen
Eine Gleitkommazahl kann in eine Übung als Aufgabenparameter eingehen
oder sie ergibt sich aus dem Ergebnis einer Berechnung. Wenn die
Eingangsparameter Zufallszahlen sind und bei der Berechnung eine Division
erforderlich ist, dann ist die Wahrscheinlichkeit hoch, dass im Ergebnis
eine Gleitkommazahl stehen wird. eEx soll die Lösung des Anwenders mit dem
Soll-Ergebnis vergleichen und
entscheiden ob die Eingabe richtig war. An dieser Stelle wird
es für ein Computerprogramm schwierig: Ein Computer kann zwar zwei
Werte auf Gleichheit prüfen (so wie das in den vorhergehenden Tutorials
geschieht), wird aber bei der kleinsten Abweichung der Lösung, selbst wenn
diese in der zehnten Stelle hinter dem Komma gefunden wird, diese als falsch
bewerten. Beispiel:
Im Aufgabenfenster (oben):
{$a1} : {$a2} = {?ea,,4}
Im Codefenster (unten):
$a1 = 1 $a2 = 7 $ea = $a1 / $a2
Das Ergebnis können Sie auch hier testen. Mit dem Parameter 4 im Ergebnisfeld {?ea1,,4} haben wir festgelegt, dass das Feld vier Stellen lang sein soll. Der Anwender kann hier das Ergebnis 0,14 eingeben. eEx wird dieses Ergebnis aber als falsch ansehen und als richtige Lösung eine Zahl mit vielen Nachkommastellen präsentieren.
Ein weiteres Problem: Wenn Sie Berechnungen unter Verwendung von Gleitkommazahlen durchführen, könnte das Ergebnis von dem zu erwartenden Resultat abweichen, selbst dann, wenn Sie das nicht erwarten.
Geben Sie in das Aufgabenfenster folgenden Text ein:
{$a1} : {$a2} = {?ea,,4}
und in das Codefenster:
$a1 = 1 / 10 $a2 = 2 / 10 $ea = $a1 * $a2
Auch diese Übung können Sie hier testen. Haben Sie als Lösung 0,02 eingegeben? Und was sagt die Prüfung der Lösung? Nun kommt es darauf an, welchen Browser sie einsetzen. Die meisten Browservarianten werden Ihre Lösung als falsch bewerten und die Zahl 0,020000000000000004 als Sol-Ergebnis anzeigen. Das ist natürlich nicht korrekt. Rundungsfehler ähnlich dem oben beschriebenen treten in jeder Programmier-sprache auf, in der Gleitkommazahlen für Berechnungen verwendet werden. Computer rechnen intern mit Binärzahlen. Da Dezimalstellen oftmals keinen exakten binären Gegenwert haben, kann es zu dieser Art von Rundungsfehlern kommen. Ähnliche Probleme gibt es auch im Dezimalsystem bei der Verwendung von irrationalen Zahlen (z.B. das Ergebnis aus Wurzel aus Zwei).
Gleitkommazahlen richtig formatieren
Im letzten Tutorial haben wir bereits über die Formatierung der Textfelder gesprochen. Hier werden wir nun den fehlenden Parameter zwischen den beiden Kommas ergänzen. Ändern Sie den Code des letzten Beispiels im Textfeld Aufgabevariante 1 wie folgt:
{$a1} : {$a2} = {?ea,2,4}
Das Ergebnis dieser kleinen Änderung können wir sofort hier testen. Was ist passiert? Mit dem Parameter „2“ haben wir eine Genauigkeit von zwei Stellen hinter dem Komma angegeben. eEx bewertet nun bei der Berechnung nur noch die angegebenen Stellen. Wenn Sie eine falsche Lösung eingeben, dann erscheint die richtige Lösung mit der angegebenen Anzahl an Nachkommastellen.
Die Anzahl der Nachkommastellen können Sie auch bei den Eingabeparametern erzwingen. Das ist zum Beispiel nützlich wenn in Ihren Aufgaben mit Geldbeträgen gerechnet wird. Beispiel:
Eie Kinokarte kostet {$a1,2} €. Wie viel Geld muss Max für {$a2} Kinokarten bezahlen? Lösung: Die Kinokarten kosten zusammen {?ae,2,5} €.
$a1 = Zufall(6,8) + Zufall(2,9) / 10 $a2 = Zufall(2,5) $ae = $a1 * $a2
Die Aufgabe hier testen.
Tipps für bessere Aufgaben
1. Wir haben gesehen, dass es durch die Umwandlung vom Dezimalsystem in das Binärsystem intern zu Darstellungsfehlern kommen kann. In unserem Beispiel hat sich diese Unschärfe erst an der 18-ten Stelle hinter dem Komma ausgewirkt. Wenn Sie jedoch diese Zahl als Zwischenergebnis in weitere Berechnungen einfließen lassen, dann könnte sich der Fehler in Folgerechnungen verschlimmern. Dem können Sie entgegen wirken, indem Sie so weit wie möglich Zwischenrechnungen mit Gleitkommazahlen vermeiden. Das letzte Beispiel kann auch wie folgt programmiert werden:
$a1 = Zufall(62,89) $a2 = Zufall(2,5) $ae = ($a1 * $a2 $ae = $ae / 10 $a1 = $a1 / 10
Bei der ersten Variante war bei der Multiplikation bereits eine Gleitkommazahl beteiligt. Durch die Codeumstellung in der neuen Version konnte das vermieden werden. Versuchen Sie also immer so lange wie möglich mit Ganzzahlen zu rechnen und wandeln Sie nur die Ausgaben und Ergebnisse durch die Division durch eine 10-er Potenz in eine Gleitkommazahl um.
2. Wenn Sie eine bestimmte Anzahl von Nachkommastellen vorsehen und die Eingangsparameter Zufallszahlen sind, dann kann es vorkommen, dass das Ergebnis eine Ganzzahl oder eine Gleitkommazahl mit weniger Nachkommastellen ist. Der Parameter erzwingt jedoch die vorgegebene Anzahl von Nachkommastellen. Das hat zur Folge, dass am Ende der Zahl entsprechend der Vorgabe Nullen angehängt werden. Was für Geldbeträge noch sinnvoll ist, stört bei anderen Zahlen.
Um das zu vermeiden, können Sie den Parameter für die Nachkommastellen als negative Zahl angeben. Diese bewirkt dass Nullen am Ende der Gleitkommazahl wieder entfernt werden. Beispiel:
Angenommen die Variable $a1 hat den Wert 0,2005. Daraus ergeben sich folgende Ausgaben:
{$a1} ergibt 0,2005
{$a1,2} ergibt 0,20
{$a1,-2} ergibt 0,2
3. Wenn Sie im Ergebnis eine Gleitkommazahl mit einer bestimmten Anzahl von Nachkommastellen erwarten, dann teilen Sie das Ihren Anwendern mit. Unter dem Aufgaben- oder Übungstext können Sie angeben, welche Berechnungsgenauigkeit im Ergebnis erwartet wird. Beispiel:
Berechne den Umfang eines Kreises mit Radius R={$r1}. Rechne bei allen Gleitkommazahlen mit einer Genauigkeit von zwei Stellen hinter dem Komma. Schneide die restlichen Zahlen ab und verwende keine Rundungen.