1. Runden reeller Zahlen
Wie wir bereits besprochen haben, wird bei der Zuweisung einer reellen Zahl an eine int
Variable diese immer auf die nächstkleinere Ganzzahl abgerundet – der Bruchteil wird einfach verworfen.
Aber man kann sich leicht eine Situation vorstellen, in der eine Bruchzahl in beide Richtungen auf die nächste ganze Zahl gerundet oder sogar aufgerundet werden muss. Was machen Sie in diesem Fall?
Für diese und viele ähnliche Situationen gibt es in Java die Math
Klasse, die über die Methoden round()
, ceil()
und verfügt floor()
.
Math.round()
Methode
Die Math.round()
Methode rundet eine Zahl auf die nächste ganze Zahl:
long x = Math.round(real_number)
Aber hier gibt es noch eine weitere Nuance: Diese Methode gibt eine long
Ganzzahl zurück (kein int
). Da reelle Zahlen sehr groß sein können, haben sich die Entwickler von Java entschieden, den größten verfügbaren Integer-Typ von Java zu verwenden: long
.
Wenn ein Programmierer dementsprechend das Ergebnis einer int
Variablen zuweisen möchte, muss er dem Compiler explizit mitteilen, dass er den möglichen Datenverlust akzeptiert (für den Fall, dass die resultierende Zahl nicht in einen int
Typ passt).
int x = (int) Math.round(real_number)
Beispiele:
Stellungnahme | Ergebnis |
---|---|
|
|
|
|
|
|
Math.ceil()
Methode
Die Math.ceil()
Methode rundet eine Zahl auf eine ganze Zahl auf. Hier sind Beispiele:
Stellungnahme | Ergebnis |
---|---|
|
|
|
|
|
|
Math.floor()
Methode
Die Math.floor()
Methode rundet eine Zahl auf eine ganze Zahl ab . Hier sind Beispiele:
Stellungnahme | Ergebnis |
---|---|
|
|
|
|
|
|
Wenn Sie eine Zahl auf eine ganze Zahl abrunden, ist es natürlich einfacher, einfach einen Typumwandlungsoperator zu verwenden:(int)
Stellungnahme | Ergebnis |
---|---|
|
|
Wenn es Ihnen schwerfällt, sich diese Namen zu merken, hilft eine kurze Englischlektion:
Math
bedeutet MathematikRound
bedeutet rundCeiling
bedeutet DeckeFloor
bedeutet Boden
2. Wie Gleitkommazahlen aufgebaut sind
Der double
Typ kann Werte im Bereich von bis speichern . Dieser große Wertebereich (im Vergleich zum Typ) erklärt sich aus der Tatsache, dass der Typ (wie auch ) eine völlig andere interne Struktur hat als Integer-Typen. Intern kodiert der Typ seinen Wert als zwei Zahlen: Die erste wird Mantisse und die zweite Exponent genannt .-1.7*10308
+1.7*10308
int
double
float
double
Nehmen wir an, wir haben die Zahl 123456789
und speichern sie als double
Variable. Wenn wir das tun, wird die Zahl in konvertiert und der Typ speichert intern zwei Zahlen – und . Der Signifikand („signifikanter Teil der Zahl“ oder Mantisse) wird rot hervorgehoben, während der Exponent blau hervorgehoben wird.1.23456789*108
double
23456789
8
Dieser Ansatz ermöglicht die Speicherung sowohl sehr großer als auch sehr kleiner Zahlen. Da die Darstellung der Zahl jedoch auf 8 Bytes (64 Bit) begrenzt ist und einige der Bits zum Speichern des Exponenten (sowie des Vorzeichens der Mantisse und des Exponenten) verwendet werden, sind die maximal verfügbaren Ziffern zur Darstellung der Mantisse verfügbar ist 15 .
Dies ist eine sehr vereinfachte Beschreibung der Struktur reeller Zahlen.
3. Präzisionsverlust beim Arbeiten mit reellen Zahlen
Bedenken Sie bei der Arbeit mit reellen Zahlen immer, dass reelle Zahlen nicht exakt sind . Bei der Konvertierung von dezimal nach binär kann es immer zu Rundungs- und Konvertierungsfehlern kommen . Darüber hinaus ist die häufigste Fehlerquelle der Genauigkeitsverlust beim Addieren/Subtrahieren von Zahlen auf völlig unterschiedlichen Skalen.
Diese letzte Tatsache ist für unerfahrene Programmierer ein wenig überwältigend.
Wenn wir von subtrahieren , erhalten wir .1/109
109
109
Subtrahieren von Zahlen auf völlig unterschiedlichen Skalen | Erläuterung |
---|---|
|
Die zweite Zahl ist extrem klein , was dazu führt, dass ihr Signifikand (grau hervorgehoben) ignoriert wird. Die 15 signifikanten Ziffern werden orange hervorgehoben. |
Was können wir sagen, Programmieren ist nicht dasselbe wie Mathematik.
4. Fallstrick beim Vergleich reeller Zahlen
Eine weitere Gefahr lauert auf Programmierer, wenn sie reelle Zahlen vergleichen. Es entsteht bei der Arbeit mit reellen Zahlen, weil sich Rundungsfehler anhäufen können. Das Ergebnis ist, dass es Situationen gibt, in denen erwartet wird, dass die reellen Zahlen gleich sind, dies aber nicht der Fall ist. Oder umgekehrt: Es wird erwartet, dass die Zahlen unterschiedlich sind, aber sie sind gleich.
Beispiel:
Stellungnahme | Erläuterung |
---|---|
|
Der Wert der Variablen a beträgt 1000000000.0 Der Wert der Variablen c beträgt 1000000000.0 (die Zahl in der b Variablen ist zu klein) |
Im obigen Beispiel sollten a
und c
nicht gleich sein, aber sie sind es.
Oder nehmen wir ein anderes Beispiel:
Stellungnahme | Erläuterung |
---|---|
|
Der Wert der Variablen a wird sein. 1.0 Der Wert der Variablen b wird sein1.0 |
5. Eine interessante Tatsache überstrictfp
Java hat ein spezielles strictfp
Schlüsselwort ( strict floating point ), das in anderen Programmiersprachen nicht zu finden ist . Und wissen Sie, warum Sie es brauchen? Es verschlechtert die Genauigkeit von Operationen mit Gleitkommazahlen. Hier ist die Geschichte, wie es dazu kam:
GO TO FULL VERSION