Betrachten Sie die folgende Schleife, in der i bisher nicht deklariert ist:
while (i == i + 1) {}
Suchen Sie die Definition von i
, die dieser Schleife vorausgeht, sodass die while-Schleife für immer fortgesetzt wird.
Die nächste Frage, die dieselbe Frage für dieses Code-Snippet stellte:
while (i != i) {}
war mir klar. Natürlich ist es in dieser anderen Situation so, NaN
aber ich stecke wirklich in der vorherigen fest. Hat das mit Überlauf zu tun? Was würde dazu führen, dass eine solche Schleife in Java für immer wiederholt wird?
.equals()
Methode zu überschreiben ? Da ich nicht deklariert bin, können wir jede Klasse von dem verwenden, was wir wollen.null
, da diesnull == null
wahr ist undnull + 1
istnull
.0.2 + 0.1 == 0.3
sich der Wert abhängig von den Compilereinstellungen, der Mondphase usw. ändert.Antworten:
Da die
while (i == i + 1) {}
Schleife den Wert von nicht änderti
, ist es zunächst äquivalent, diese Schleife unendlich zu machen, um einen Wert zu wähleni
, der erfüllti == i + 1
.Es gibt viele solche Werte:
Beginnen wir mit den "exotischen":
oder
Der Grund für die Erfüllung dieser Werte
i == i + 1
ist inJLS 15.18.2 angegeben. Additive Operatoren (+ und -) für numerische Typen :
Dies ist nicht überraschend, da das Hinzufügen eines endlichen Wertes zu einem unendlichen Wert zu einem unendlichen Wert führen sollte.
Das heißt, die meisten Werte
i
, die erfüllen,i == i + 1
sind einfach großedouble
(oderfloat
) Werte:Beispielsweise:
oder
oder
Die
double
undfloat
-Typen haben eine begrenzte Genauigkeit. Wenn Sie also einen ausreichend großen Wertdouble
oderfloat
Wert verwenden, führt das Hinzufügen1
zu demselben Wert.quelle
(double)(1L<<53)
- oderfloat i = (float)(1<<24)
Diese Rätsel werden ausführlich im Buch "Java Puzzlers: Fallen, Fallstricke und Eckfälle" von Joshua Bloch und Neal Gafter beschrieben.
oder:
Beides führt zu einer Endlosschleife, da durch Hinzufügen
1
zu einem ausreichend großen Gleitkommawert der Wert nicht geändert wird, da die Lücke zu seinem Nachfolger 1 nicht "überbrückt" wird .Ein Hinweis zum zweiten Puzzle (für zukünftige Leser):
führt auch zu einer Endlosschleife, da NaN keinem Gleitkommawert entspricht, einschließlich sich selbst 2 .
1 - Java-Puzzler: Fallen, Fallstricke und Eckfälle (Kapitel 4 - Loopy-Puzzler).
2 - JLS §15.21.1
quelle
double i = Double.POSITIVE_INFINITY;
quelle
Nur eine Idee: Was ist mit Booleschen?
Ist das nicht ein Fall wo
i + 1 == i
?quelle
+
Operator hat, der aboolean
und aint
als Operanden verwendet).