Considere el siguiente ciclo, en el que, hasta ahora, no está declarado:
while (i == i + 1) {}
Encuentre la definición de i
, que precede a este bucle, de modo que el bucle while continúe para siempre.
La siguiente pregunta, que hizo la misma pregunta para este fragmento de código:
while (i != i) {}
fue obvio para mí. Por supuesto que en esta otra situación lo es, NaN
pero estoy realmente atascado en la anterior. ¿Tiene esto que ver con el desbordamiento? ¿Qué haría que tal bucle se repita para siempre en Java?
.equals()
método? Dado que i no está declarado, podemos usar cualquier clase de lo que queramos.null
, ya quenull == null
es verdadero ynull + 1
esnull
.0.2 + 0.1 == 0.3
cambia su valor según la configuración del compilador, la fase de la luna, etc.Respuestas:
En primer lugar, dado que el
while (i == i + 1) {}
ciclo no cambia el valor dei
, hacer que este ciclo sea infinito es equivalente a elegir un valor dei
que satisfagai == i + 1
.Hay muchos valores de este tipo:
Empecemos por los "exóticos":
o
La razón por la que estos valores son satisfactorios
i == i + 1
se establece enJLS 15.18.2. Operadores aditivos (+ y -) para tipos numéricos :
Esto no es sorprendente, ya que agregar un valor finito a un valor infinito debería resultar en un valor infinito.
Dicho esto, la mayoría de los valores
i
que satisfaceni == i + 1
son simplemente valores grandesdouble
(ofloat
):Por ejemplo:
o
o
Los tipos
double
yfloat
tienen una precisión limitada, por lo que si toma un valordouble
o lo suficientemente grandefloat
, agregarlo1
dará como resultado el mismo valor.fuente
(double)(1L<<53)
- ofloat i = (float)(1<<24)
Estos rompecabezas se describen en detalle en el libro "Java Puzzlers: Traps, Pitfalls, and Corner Cases" de Joshua Bloch y Neal Gafter.
o:
ambos darán como resultado un bucle infinito, porque agregar
1
a un valor de coma flotante que sea suficientemente grande no cambiará el valor, porque no "cierra la brecha" con su sucesor 1 .Una nota sobre el segundo acertijo (para futuros lectores):
también da como resultado un bucle infinito, porque NaN no es igual a ningún valor de punto flotante, incluido él mismo 2 .
1 - Rompecabezas de Java: trampas, trampas y casos de esquina (capítulo 4 - Rompecabezas de loopy).
2 - JLS §15.21.1
fuente
double i = Double.POSITIVE_INFINITY;
fuente
Solo una idea: ¿qué pasa con los booleanos?
¿No es este un caso donde
i + 1 == i
?fuente
+
operador que tome aboolean
y aint
como operandos).