Considérez la boucle suivante, dans laquelle i est, jusqu'à présent, non déclaré:
while (i == i + 1) {}
Trouvez la définition de i
, qui précède cette boucle, de telle sorte que la boucle while continue pour toujours.
La question suivante, qui posait la même question pour cet extrait de code:
while (i != i) {}
était évident pour moi. Bien sûr, dans cette autre situation, c'est le cas, NaN
mais je suis vraiment coincé sur la précédente. Est-ce que cela a à voir avec le débordement? Pourquoi une telle boucle ferait-elle une boucle éternelle en Java?
.equals()
méthode? Puisque i n'est pas déclaré, nous pouvons utiliser n'importe quelle classe de ce que nous voulons.null
, puisquenull == null
est vrai, etnull + 1
estnull
.0.2 + 0.1 == 0.3
change sa valeur en fonction des paramètres du compilateur, de la phase de la lune, etc.Réponses:
Tout d'abord, puisque la
while (i == i + 1) {}
boucle ne change pas la valeur dei
, rendre cette boucle infinie équivaut à choisir une valeur dei
qui satisfaiti == i + 1
.Il existe de nombreuses valeurs de ce type:
Commençons par les "exotiques":
ou
La raison pour laquelle ces valeurs satisfont
i == i + 1
est indiquée dansJLS 15.18.2. Opérateurs additifs (+ et -) pour les types numériques :
Cela n'est pas surprenant, car l'ajout d'une valeur finie à une valeur infinie devrait entraîner une valeur infinie.
Cela dit, la plupart des valeurs de
i
qui satisfonti == i + 1
sont simplement des valeurs grandesdouble
(oufloat
):Par exemple:
ou
ou
Les types
double
etfloat
ont une précision limitée, donc si vous prenez une valeurdouble
ou assez grandefloat
, l'ajout1
de celle-ci donnera la même valeur.la source
(double)(1L<<53)
- oufloat i = (float)(1<<24)
Ces puzzles sont décrits en détail dans le livre "Java Puzzlers: Traps, Pitfalls, and Corner Cases" de Joshua Bloch et Neal Gafter.
ou:
les deux résulteront en une boucle infinie, car l'ajout
1
d'une valeur à virgule flottante suffisamment grande ne changera pas la valeur, car elle ne «comble pas l'écart» avec son successeur 1 .Une note sur le deuxième puzzle (pour les futurs lecteurs):
entraîne également une boucle infinie, car NaN n'est égal à aucune valeur à virgule flottante, y compris lui-même 2 .
1 - Puzzlers Java: pièges, pièges et cas de coin (chapitre 4 - Puzzlers Loopy).
2 - JLS §15.21.1
la source
double i = Double.POSITIVE_INFINITY;
la source
Juste une idée: qu'en est-il des booléens?
N'est-ce pas un cas où
i + 1 == i
?la source
+
opérateur qui prend aboolean
et anint
comme opérandes).