Abschließend möchte ich noch auf einige Dinge hinweisen, die beim Schreiben von numerischen Programmen zu beachten sind.
Einer der wichtigsten Punkte, die bei numerischen Berechnungen zu beachten ist, ist das Problem der Fehler. Numerische Berechnungen sind ein Kampf gegen Fehler. (Darüber hinaus kämpfen wir auch mit der Rechenzeit und der Speicherkapazität. Es gibt viele Feinde.)
Hier werde ich einige sehr einfache Beispiele vorstellen.
Vorsicht vor Dezimalbruch
Auf den ersten Blick könnte die Zahl 0.1 wie eine saubere
Zahl aussehen.
Das liegt aber nur an der besonderen
Situation des
Dezimalsystems, was anderswo nicht unbedingt der Fall ist.
In der Tat ist die binäre Darstellung von 0.1
0.000110011…
was ein unendlicher binärer Bruch ist.
Da Computer intern Binärzahlen verarbeiten und nicht mit unendlich vielen Ziffern umgehen können, müssen sie irgendwo auf- oder abrunden. Dies führt zu einem Fehler (Rundungsfehler).
Aus diesem Grund ergibt die zehnfache Addition von 0.1 nicht immer 1.
Überlegen Sie, was passiert (oder passieren sollte), wenn Sie das folgende Programm ausführen. Geben Sie dann dieses Programm in das Textfeld ein und versuchen Sie, es auszuführen.
let sum = 0;
for (let i = 0; i < 10; i++) {
sum += 0.1;
console.log(sum)
}
Sie werden wahrscheinlich das folgende Ergebnis erhalten.
0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.7999999999999999 0.8999999999999999 0.9999999999999999
Daher führt der Vergleich von Dezimalzahlen mit ==
nicht immer zu dem erwarteten Ergebnis.
Überlegen Sie, was passiert (oder passieren sollte), wenn Sie das folgende Programm ausführen. Geben Sie dann dieses Programm in das Textfeld ein und versuchen Sie, es auszuführen.
let sum = 0;
for (let i = 0; i < 20; i++) {
sum += 0.1;
if (sum == 1) {
console.log("Now sum is 1");
}
}
console.log("sum is ", sum);
==
.
Vorsicht bei der Subtraktion
Die Subtraktion von sehr nahen
Zahlen (ein sehr vager Begriff, auf
den wir hier aber nicht näher eingehen wollen) führt manchmal nicht
zum erwarteten Ergebnis.
Nehmen wir zum Beispiel $1.00000001 - 1$.
-
Berechnen Sie $(1.00000001 - 1)$ mit Papier und Bleistift.
-
Führen Sie diese Berechnung mit dem folgenden Programm durch.
let n1 = 1.00000001;
let n2 = 1;
let answer = 0.00000001;
console.log(n1 - n2);
console.log("The answer should be:", answer);
Wie dieses Beispiel zeigt, ist es nicht so, dass die Zahl 0.00000001 (= 1e-08
)
nicht dargestellt werden kann (answer
wird korrekt dargestellt),
sondern dass der Fehler durch die Subtraktion verursacht wird.
Aufgrund dieses Problems wird die numerische Differenzierung im
Allgemeinen als eine der schwierigeren
Berechnungen für
Computer angesehen.
Nun möchten Sie vielleicht fragen:
Wie genau kann ich dieses Problem vermeiden?
Leider kommt es darauf an.
Man kann beispielsweise die Reihenfolge der Berechnungen ändern, oder
man kann den Algorithmus ändern, aber welche Methode am besten ist,
hängt vom Problem ab.
Vorsicht bei der Addition
Die Addition von sehr großen und sehr kleinen Zahlen funktioniert eventuell nicht.
Das folgende Programm addiert 100 Mal 1e-10
($= 0.000 000 000 1$) zu
1e7
($= 10,000,000$).
Führen Sie das aus.
let n1 = 1e7;
let n2 = 1e-10;
let n = n1;
for (let i = 0; i < 100; i++) {
n += n2;
}
console.log(n);
let answer = n1 + n2 * 100;
console.log("The answer should be:", answer);
Diese ist leichter zu verstehen, wenn man sie in Dezimalzahlen betrachtet. Bei drei signifikanten Stellen ergibt die Addition von 0.01 zu 10.0 $$ 10.0 + 0.01 = 10.0\cancel{1} = 10.0 \quad . $$ Es ist also egal, wie oft 0.01 zu 10.0 addiert wird, es ist immer noch 10.0.
Dieses Problem kann auftreten, wenn die Anzahl der Teilungen bei der numerischen Integration extrem groß ist.