1.1 Runden von Gleitkommazahlen
Gleitkommazahlen nennt man auf Englisch floating point number – Zahlen mit Gleitkomma: In den USA wird ein Punkt verwendet, um den ganzzahligen und den gebrochenen Teil einer Zahl zu trennen. Daher der Name float.
Wie wir bereits besprochen haben, wird bei der Umwandlung einer Gleitkommazahl (float) in eine Ganzzahl (int) immer abgerundet – der gebrochene Teil wird einfach verworfen. Man kann sich leicht Situationen vorstellen, in denen eine Gleitkommazahl einfach auf die nächste ganze Zahl oder sogar aufrunden werden muss. Was tun?
Für diesen Fall gibt es in JavaScript die eingebaute Funktion round()
. Sie wurde vor der Erstellung der Bibliothek Math erfunden, deshalb gehört sie nicht dazu. Die Funktionen zum Abrunden nach unten und zum Aufrunden befinden sich in der Bibliothek math.
Funktion Math.round()
Die Funktion Math.round()
rundet eine Zahl zur nächstgelegenen ganzen Zahl:
Math.round(gleitkommazahl)
Diese Funktion gibt eine ganze Zahl zurück, die näher an der übergebenen Gleitkommazahl liegt.
Beispiele:
Befehl | Ergebnis |
---|---|
let x = Math.round(4.1); |
4 |
let x = Math.round(4.5); |
5 |
let x = Math.round(4.9); |
5 |
Funktion Math.ceil()
Die Funktion Math.ceil()
rundet eine Zahl zur nächsten ganzen Zahl auf:
Befehl | Ergebnis |
---|---|
let x = Math.ceil(4.1); |
5 |
let x = Math.ceil(4.5); |
5 |
let x = Math.ceil(4.9); |
5 |
Funktion Math.floor()
Die Funktion Math.floor()
rundet eine Zahl zur nächsten ganzen Zahl ab:
Befehl | Ergebnis |
---|---|
let x = Math.floor(4.1); |
4 |
let x = Math.floor(4.5); |
4 |
let x = Math.floor(4.9); |
4 |
Wenn es dir schwerfällt, dir diese Befehle zu merken, hilft dir ein kleiner Englischunterricht:
- math — Mathematik
- round — rund/aufrunden
- ceiling — Decke
- floor — Boden
1.2 Aufbau von Gleitkommazahlen
Der Typ number in JavaScript kann Werte im Bereich von -1.7*10308 bis +1.7*10308 speichern. Dieser riesige Wertebereich ist darauf zurückzuführen, dass der Typ number ganz anders aufgebaut ist als Ganzzahlen. Jede Variable des Typs number enthält zwei Zahlen: Die erste wird Mantisse genannt, die zweite — Exponent.
Angenommen, wir haben die Zahl 123456789 und speichern sie in einer Variablen des Typs number. Dann wird die Zahl in die Form 1.23456789*108 umgewandelt, und innerhalb des Typs number werden die Zahlen 1.23456789 und 8 gespeichert. Rot markiert ist der "signifikante Teil der Zahl" (Mantisse), blau der Exponent.
Dieser Ansatz ermöglicht es, sowohl sehr große als auch sehr kleine Zahlen zu speichern. Da jedoch die Größe der Zahl auf 8 Bytes (64 Bits) beschränkt ist und ein Teil der Bits zur Speicherung des Exponents (sowie des Vorzeichens der Zahl und des Exponenten) verwendet wird, ist die maximale Länge der Mantisse auf 15 Ziffern begrenzt.
Dies ist eine sehr vereinfacht Darstellung des Aufbaus von Gleitkommazahlen: eine ausführlichere findet man unter diesem Link.
1.3 Verlust der Genauigkeit bei der Arbeit mit Gleitkommazahlen
Bei der Arbeit mit Gleitkommazahlen muss man stets beachten, dass Gleitkommazahlen ungenau sind. Es wird immer Rundungsfehler, Umwandlungsfehler von Dezimal- in Binärsystem und schließlich am häufigsten Genauigkeitsverlust bei der Addition/Subtraktion von Zahlen mit sehr unterschiedlicher Größenordnung geben.
Letzteres ist die unerwartetste Situation für Programmieranfänger.
Wenn man von der Zahl 109 die Zahl 1/109 abzieht, erhält man wieder 109.
Subtraktion von Zahlen mit sehr unterschiedlicher Größenordnung | Erklärung |
---|---|
1000000000.000000000 - 0.000000001 1000000000.000000000 |
Die zweite Zahl ist zu klein, und ihr signifikanter Teil wird ignoriert (grau markiert). Rot markiert sind 15 signifikante Ziffern. |
Tja, Programmierung ist nicht Mathematik.
1.4 Gefahr des Vergleichs von Gleitkommazahlen
Eine weitere Gefahr lauert auf Programmierer beim Vergleich von Gleitkommazahlen. Da sich bei der Arbeit mit diesen Zahlen Rundungsfehler anhäufen können, sind Situationen möglich, in denen Gleitkommazahlen gleich sein sollten, es aber nicht sind. Und umgekehrt: Zahlen sollten nicht gleich sein, sind es aber.
Beispiel:
Befehl | Erklärung |
---|---|
let a = 1000000000.0 let b = 0.000000001 let c = a – b
|
In der Variablen a wird der Wert 1000000000.0 sein.In der Variablen c wird der Wert 1000000000.0 sein(die Zahl in der Variablen b ist zu klein).
|
Im obigen Beispiel sollten a
und c
nicht gleich sein, sind es aber.
Oder ein anderes Beispiel:
Befehl | Erklärung |
---|---|
let a = 1.00000000000000001 let b = 1.00000000000000002
|
In der Variablen a wird der Wert 1.0 sein.In der Variablen b wird der Wert 1.0 sein.
|
In der Praxis vergleicht man Gleitkommazahlen wie folgt:
Wenn der Unterschied der Zahlen (im Betrag) kleiner ist als eine sehr kleine Zahl, gelten sie als gleich.
Beispiel:
let a = 0.00000000012;
let b = 0.000000000011;
if (Math.abs(a - b) < 0.00001) {
console.log("gleich");
} else {
console.log("nicht gleich");
}
GO TO FULL VERSION