Inhaltsverzeichnis:
Video: String Theory Explained – What is The True Nature of Reality? 2024
Ob Sie es glauben oder nicht, Computer - selbst die leistungsstärksten - haben gewisse Einschränkungen, wenn es darum geht, mathematische Berechnungen durchzuführen. Diese Einschränkungen sind normalerweise unbedeutend, aber manchmal schleichen sie sich an und beißen Sie. Hier sind die Dinge, auf die Sie bei der Mathematik in Java achten müssen.
Ganzzahliger Überlauf
Das grundlegende Problem bei Integer-Typen ist, dass sie eine feste Größe haben. Als Ergebnis gibt es eine Grenze für die Größe der Zahlen, die in Variablen des Typs
short
,
int
oder
long
gespeichert werden können. Obwohl
lange
Variablen sehr große Zahlen enthalten können, stoßen Sie früher oder später auf eine Zahl, die zu groß ist, um in eine
lange
Variable zu passen.
Okay, betrachten Sie dieses (zugegebenermaßen erfundene) Beispiel:
int a = 1000000000;
System. aus. Druck (a);
a + = 1000000000;
System. aus. Druck (a);
a + = 1000000000;
System. aus. Druck (a);
a + = 1000000000;
System. aus. Druck (a);
Hier erwarten Sie, dass der Wert von
a
nach jeder Addition größer wird. Aber hier ist die Ausgabe, die angezeigt wird:
1000000000
2000000000
-1294967296
-294967296
Die erste Addition scheint zu funktionieren, aber danach wird die Zahl negativ! Das liegt daran, dass der Wert die Größenbeschränkung des Datentyps
int
erreicht hat. Leider sagt Ihnen Java nicht, dass dieser Fehler aufgetreten ist. Es stoppt einfach die Variable
int
so voll wie möglich, verwirft alle Bits, die nicht passen, und hofft, dass Sie es nicht bemerken. Aufgrund der Art und Weise, wie
int
negative Werte speichert, werden große positive Werte plötzlich zu großen negativen Werten.
Die Moral der Geschichte ist, dass wenn Sie mit großen ganzen Zahlen arbeiten, Sie
lang
anstelle von
int
verwenden sollten, weil
lang
kann viel größere Zahlen als
int
speichern. Wenn Ihre Programme mit Zahlen arbeiten, die groß genug sind, um
lang
ein Problem zu sein, sollten Sie statt dessen Gleitkommatypen verwenden. Fließkomma-Typen können sogar größere Werte als
long
verarbeiten, und sie informieren Sie, wenn Sie ihre Kapazität überschreiten.
Gleitpunkt-Verrücktheit
Gleitkommazahlen haben eigene Probleme. Für den Anfang werden Fließkommazahlen unter Verwendung des binären Zahlensystems (Basis 2) gespeichert, aber Menschen arbeiten mit Zahlen im Dezimalzahlensystem (Basis 10). Leider ist es manchmal unmöglich, Zahlen zwischen diesen beiden Systemen genau umzuwandeln. Das liegt daran, dass bestimmte Brüche in jeder Zahlenbasis nicht exakt dargestellt werden können.
Ein Beispiel: Die Basis 10 hat keine Möglichkeit, den Bruchteil von 1/3 genau darzustellen. Sie können es als 0.3333333 approximieren, aber schließlich erreichen Sie die Grenze, wie viele Ziffern Sie speichern können, also müssen Sie aufhören. In der Basis 2 passiert es, dass einer der Bruchteile, den Sie nicht genau darstellen können, der Dezimalwert 1/10 ist. Mit anderen Worten, eine
float
oder
double
Variable kann
0 nicht genau darstellen. 1
.
Versuchen Sie, diesen Code auszuführen:
float x = 0. 1f;
NumberFormat nf = Zahlenformat. getNumberInstance ();
nf. setMinimumFractionDigits (10);
System. aus. println (nf. Format (x));
Die resultierende Ausgabe ist dies:
0. 1000000015
Obwohl
0. 1000000015
ist nah bis
0. 1
, ist es nicht genau.
In den meisten Fällen ist die Fließkomma-Mathematik von Java nahe genug, um keine Rolle zu spielen. Die Fehlerquote ist extrem klein. Wenn Sie Java verwenden, um die Größe Ihres Hauses zu messen, benötigen Sie ein Elektronenmikroskop, um den Fehler zu erkennen. Wenn Sie jedoch Anwendungen schreiben, die sich mit Finanztransaktionen befassen, kann normales Runden die Fehler manchmal vergrößern, um sie signifikant zu machen. Sie können einen Penny zu viel oder zu wenig Umsatzsteuer verlangen. Und in extremen Fällen können Ihre Rechnungen tatsächlich offensichtliche Additionsfehler aufweisen.
Integer-Typen werden natürlich auch binär gespeichert. Aber Ganzzahlen unterliegen nicht den gleichen Fehlern wie Gleitkommatypen - da Ganzzahlen überhaupt keine Brüche darstellen, so dass Sie sich bei
Ganzzahlen
nicht um diese Art von Fehler kümmern müssen.
Division durch Null
Nach den Grundregeln der Mathematik können Sie eine Zahl nicht durch Null teilen. Der Grund ist einfach: Division ist die Umkehrung der Multiplikation - was bedeutet, dass, wenn
a * b = c
gilt, auch
a = c / b
gilt. Wenn Sie zulassen würden, dass
b
Null ist, wäre die Division bedeutungslos, da eine beliebige Zahl mal Null Null ist. Daher müssten sowohl
a
als auch
c
ebenfalls Null sein. Kurz gesagt, Mathematiker haben dieses Dilemma vor Jahrhunderten gelöst, indem sie sagten, dass eine Division durch Null einfach nicht erlaubt ist.
Was passiert also, wenn Sie versuchen, in einem Java-Programm eine Zahl durch Null zu teilen? Die Antwort hängt davon ab, ob Sie Ganzzahlen oder Gleitkommazahlen teilen. Wenn Sie ganze Zahlen teilen, wird durch die Anweisung, die die Division durch Null versucht, eine so genannte -Ausnahme aufgefrischt,, was eine unhöfliche Art ist, das Programm zu stürzen.
Es gibt eine Möglichkeit, diese Ausnahme abzufangen, damit Ihr Programm fortgesetzt werden kann, was Sie hier nicht herausfinden. In der Zwischenzeit stürzt jedes Programm ab, das Sie schreiben und das eine Ganzzahl-Division durch Null versucht.
Wenn Sie versuchen, einen Gleitkommatyp durch Null zu teilen, sind die Ergebnisse nicht so abrupt. Stattdessen ordnet Java dem Gleitkomma-Ergebnis einen der speziellen Werte zu, die in der folgenden Tabelle aufgeführt sind. In den folgenden Abschnitten wird erklärt, wie diese speziellen Werte bestimmt werden:
- Wenn Sie eine Zahl durch Null teilen und das Vorzeichen beider Zahlen gleich ist, ist das Ergebnis positiv unendlich.
0. 0
geteilt durch0. 0
ist positiv unendlich, ebenso wie-34. 0
geteilt durch-0. 0
. - Wenn Sie eine Zahl durch Null teilen und die Vorzeichen der Zahlen unterschiedlich sind, ist das Ergebnis negativ unendlich.
-40. 0
geteilt durch0. 0
ist negative Unendlichkeit, wie34. 0
geteilt durch0. 0
. - Wenn Sie Null durch Null dividieren, ist das Ergebnis unabhängig von den Vorzeichen keine Zahl (NaN).
Konstante | Bedeutung |
POSITIVE_INFINITY
|
Positive Unendlichkeit |
NEGATIVE_INFINITY
|
Negative Unendlichkeit |
NaN
|
Keine Zahl |
Fließkomma-Nullen können positiv oder negativ sein. Java betrachtet positive und negative Nullen als numerisch gleich.
Wenn Sie versuchen, einen Gleitkommawert zu drucken, der einen dieser speziellen Werte hat, konvertiert Java den Wert in eine entsprechende Zeichenfolge. Angenommen, Sie führen die folgenden Anweisungen aus:
double x = Math. sqrt (-50); // keine Zahl
double y = x;
if (x == y)
System. aus. println ("x ist gleich y");
Die resultierende Konsolenausgabe ist
Infinity
, wenn
i
-50 war. 0
, würde die Konsole
-Infinity
anzeigen, und wenn
i
null wäre, würde die Konsole
NaN
anzeigen.
Die folgenden Absätze beschreiben einige abschließende Bits der Verrücktheit:
-
NaN
ist nicht mit sich selbst identisch, was einige seltsame Konsequenzen haben kann. Zum Beispiel:
double x = Math. sqrt (-50); // keine Zahl
double y = x;
if (x == y)
System. aus. println ("x ist gleich y");
Nehmen Sie zum Argument an, dass die
if
-Anweisung testet, ob die Variable
x
gleich der Variablen
y
ist. Da dieser Test unmittelbar auf eine Zuweisungsanweisung folgt, die den Wert von
x
an
y
anweist, können Sie sicher annehmen, dass
x
gleich
y
ist. Recht?
Falsch. Weil
x
NaN
ist, ist
y
auch
NaN
.
NaN
wird niemals als gleichwertig mit einem anderen Wert angesehen, einschließlich eines anderen
NaN
. Daher schlägt der Vergleich in der Anweisung
if
fehl.
- Eine weitere seltsame Konsequenz: Sie können nicht davon ausgehen, dass eine Zahl minus sich selbst immer Null ist. Betrachten Sie diese Aussage:
double z = x - x; // nicht unbedingt Null
Sollte diese Anweisung nicht immer
z
auf Null setzen? Nicht wenn
x
NaN
ist. In diesem Fall ist keine Zahl minus keine Zahl immer noch keine Zahl.
- Noch eine Verrücktheit: Jede mathematische Operation mit Unendlichkeit führt entweder zu einer anderen Unendlichkeit oder zu
NaN
. Unendlichkeit + 5 zum Beispiel ist immer noch unendlich, also ruft Buzz Lightyears "In die Unendlichkeit und darüber hinaus! "Es wird einfach nicht passieren. Aber unendlich minus unendlich gibt Ihnen …NaN
.