Eu tenho a seguinte if
condição.
if (i == -i && i != 0)
Qual valor de i
retornará true
para esta condição em Java?
Não consigo pensar em qualquer valor de i
considerar a notação de complemento de dois em Java.
Eu também adoraria ter uma prova algébrica de qualquer resposta que essa condição tenha (no contexto com Java).
-0.0
também é== 0
if(i && i == -i)
Respostas:
O único
int
valor para o qual funciona éInteger.MIN_VALUE
.É porque os inteiros são negados usando a forma de complemento de dois .
Usando
você vê que
Integer.MIN_VALUE
éObter o valor negativo é feito primeiro trocando
0
e1
, o que dáe adicionando
1
, o que dáComo você pode ver no link que eu dei, a Wikipedia menciona o problema com os números mais negativos e especifica que é a única exceção:
Claro que você tem o mesmo fenômeno
Long.Min_Value
se você armazená-lo em umalong
variável.Observe que isso se deve apenas às escolhas feitas em relação ao armazenamento binário de ints em Java . Outra (má) solução poderia, por exemplo, ter sido negar simplesmente mudando o bit mais significativo e deixando os outros bits inalterados, isso teria evitado este problema com MIN_VALUE, mas teria feito 2
0
valores diferentes e aritmética binária complicada (como você faria incrementado, por exemplo?).fonte
O valor que você está procurando é
Integer.MIN_VALUE
.Isso está fora do tópico do Stack Exchange. Mas você poderia fazer isso a partir da definição de inteiros Java ( JLS 4.2 )
e
e a definição do operador '-' unário Java ( JLS 15.15.4 ):
fonte
i != -i
). Isso deixa dois números no intervalo:0
eInteger.MIN_VALUE
. Por causa doi != 0
seu se, sóMIN_VALUE
resta.Além das respostas dadas até agora ...
Existem quatro valores no total
Os valores agrupados são desempacotados, portanto, também são verdadeiros para esta expressão.
Nota: documentos Math.abs.
e
É surpreendente que Math.abs possa retornar um número negativo. Isso acontece porque a) não há valores positivos para -MIN_VALUE nesses casos b) realizar o
-
cálculo resulta em um estouro.O que também é interessante é por que Byte.MIN_VALUE, Short.MIN_VALUE não fazem isso. Isso ocorre porque o
-
tipo mudaint
para esses e, portanto, não há estouro.Character.MIN_VALUE não tem problema porque é 0.
Float.MIN_VALUE e Double.MIN_VALUE têm um significado diferente. Estes são os menores valores representáveis maiores que zero. Assim, eles têm valores negativos válidos que não são eles próprios.
fonte
Como os outros mencionaram, isso só é cumprido por
Integer.MIN_VALUE
. Como prova, deixe-me oferecer uma explicação mais fácil de entender que não seja binária (embora ainda esteja enraizada nisso).Observe que
Integer.MIN_VALUE
é igual a-2^31
ou-2147483648
eInteger.MAX_VALUE
é igual a2^31-1
ou2147483647
.-Integer.MIN_VALUE
is2^31
, que agora é muito grande para um Integer (já que já passouMAX_VALUE
), causando um estouro de Integer, tornando-oInteger.MIN_VALUE
novamente. É o único inteiro que faz isso, poisMIN_VALUE
é o único número sem equivalente negativo além de 0.fonte
2147483648
pode aparecer no código-fonte apenas em uma circunstância: como o operando do operador menos unário (JLS 3.10.1).Prova algébrica experimental, usando
modulo 2^32
aritmética:i == -i
pode ser reescrito como2 * i == 0
(adicionandoi
em ambos os lados) oui << 1 == 0
.Essa equação tem duas soluções da forma
i == 0 >> 1
, a saber,0b
e10000000000000000000000000000000b
obtida deslocando-se para a esquerda0
ou1
para a esquerda.Excluída a solução
i == 0
, resta a soluçãoi == 100000000000000000000000000000000b
.fonte
Talvez não seja muito educativo, mas em vez de pensar, você poderia executar este código:
para ver se imprime
infinitamente :)
fonte
<