Considere o seguinte loop, no qual i é, até agora, não declarado:
while (i == i + 1) {}
Encontre a definição de i
, que precede esse loop, de modo que o loop while continue para sempre.
A próxima pergunta, que fez a mesma pergunta para este trecho de código:
while (i != i) {}
era óbvio para mim. É claro que nesta outra situação é, NaN
mas estou realmente preso à anterior. Isso tem a ver com excesso? O que causaria esse loop para sempre em Java?
.equals()
método? Como i não é declarado, podemos usar qualquer classe do que queremos.null
, uma vez quenull == null
é verdadeiro enull + 1
énull
.0.2 + 0.1 == 0.3
altera seu valor dependendo das configurações do compilador, da fase da lua e assim por diante.Respostas:
Antes de tudo, como o
while (i == i + 1) {}
loop não altera o valor dei
, tornar esse loop infinito é equivalente a escolher um valori
satisfatórioi == i + 1
.Existem muitos desses valores:
Vamos começar com os "exóticos":
ou
A razão para a satisfação desses valores
i == i + 1
é declarada emJLS 15.18.2. Operadores aditivos (+ e -) para tipos numéricos :
Isso não é surpreendente, pois a adição de um valor finito a um valor infinito deve resultar em um valor infinito.
Dito isto, a maioria dos valores
i
que satisfazemi == i + 1
são simplesmente valores grandesdouble
(oufloat
):Por exemplo:
ou
ou
Os tipos
double
efloat
têm precisão limitada; portanto, se você usar um valordouble
oufloat
valor suficientemente grande , a adição1
a ele resultará no mesmo valor.fonte
(double)(1L<<53)
- oufloat i = (float)(1<<24)
Esses quebra-cabeças são descritos em detalhes no livro "Java Puzzlers: Traps, Pitfalls and Corner Cases", de Joshua Bloch e Neal Gafter.
ou:
ambos resultarão em um loop infinito, porque a adição
1
a um valor de ponto flutuante suficientemente grande não mudará o valor, porque não "preenche a lacuna" para seu sucessor 1 .Uma observação sobre o segundo quebra-cabeça (para futuros leitores):
também resulta em um loop infinito, porque NaN não é igual a nenhum valor de ponto flutuante, incluindo ele próprio 2 .
1 - Java Puzzlers: armadilhas, armadilhas e casos de canto (capítulo 4 - Loopy Puzzlers).
2 - JLS §15.21.1
fonte
double i = Double.POSITIVE_INFINITY;
fonte
Apenas uma idéia: e os booleanos?
Não é este o caso
i + 1 == i
?fonte
+
operador que use aboolean
e aint
como operandos).