Tengo la siguiente ifcondición.
if (i == -i && i != 0)
¿Qué valor de idevolverá truepara esta condición en Java?
No puedo pensar en tal valor de iconsiderar la notación de complemento a dos en Java.
También me encantaría tener una prueba algebraica de cualquier respuesta que tenga esta condición (en contexto con Java).

-0.0también es== 0if(i && i == -i)Respuestas:
El único
intvalor por el que funciona esInteger.MIN_VALUE.Es porque los enteros se niegan usando el método del complemento a dos .
Utilizando
ves que
Integer.MIN_VALUEesLa toma del valor negativo se realiza intercambiando primero
0y1, lo que day agregando
1, que daComo puede ver en el enlace que le di, Wikipedia menciona el problema con los números más negativos y especifica que es la única excepción:
Por supuesto, tiene el mismo fenómeno
Long.Min_Valuesi lo almacena en unlongvariable.Tenga en cuenta que esto se debe únicamente a las elecciones que se hicieron con respecto al almacenamiento binario de ints en Java . Otra (mala) solución podría haber sido, por ejemplo, negar simplemente cambiando el bit más significativo y dejando los otros bits sin cambios, esto habría evitado este problema con MIN_VALUE pero habría hecho 2
0valores diferentes y una aritmética binaria complicada (¿cómo lo habría hecho? incrementado por ejemplo?).fuente
El valor que busca es
Integer.MIN_VALUE.Eso es fuera de tema para Stack Exchange. Pero puede hacerlo a partir de la definición de enteros de Java ( JLS 4.2 )
y
y la definición del operador unario '-' de Java ( JLS 15.15.4 ):
fuente
i != -i). Eso deja dos números en el rango:0yInteger.MIN_VALUE. Pori != 0en tu si, soloMIN_VALUEqueda.Además de las respuestas dadas hasta ahora ...
Hay cuatro valores en total
Los valores ajustados se desenvuelven, por lo que también son válidos para esta expresión.
Nota: documentos Math.abs.
y
Es sorprendente que Math.abs pueda devolver un número negativo. Esto sucede porque a) no hay valores positivos para -MIN_VALUE en estos casos b) realizando el
-cálculo da como resultado un desbordamiento.Lo que también interesa es por qué Byte.MIN_VALUE, Short.MIN_VALUE no hacen esto. Esto se debe a que
-cambia el tipo aintpara estos y, por lo tanto, no hay desbordamiento.Character.MIN_VALUE no tiene ningún problema porque es 0.
Float.MIN_VALUE y Double.MIN_VALUE tienen un significado diferente. Estos son el valor representable más pequeño mayor que cero. Por tanto, tienen valores negativos válidos que no son ellos mismos.
fuente
Como han mencionado los demás, esto solo se cumple con
Integer.MIN_VALUE. En cuanto a la prueba, permítanme ofrecer una explicación más fácil de entender que no sea en binario (aunque todavía tiene sus raíces en eso).Tenga en cuenta que
Integer.MIN_VALUEes igual a-2^31o-2147483648yInteger.MAX_VALUEes igual a2^31-1o2147483647.-Integer.MIN_VALUEes2^31, que ahora es demasiado grande para un Integer (ya que es pasadoMAX_VALUE), lo que provoca un desbordamiento de Integer,Integer.MIN_VALUEvolviéndolo de nuevo. Es el único entero que hace esto, ya queMIN_VALUEes el único número sin equivalente negativo aparte de 0.fuente
2147483648puede aparecer en el código fuente solo en una circunstancia: como operando del operador menos unario (JLS 3.10.1).Prueba algebraica provisional, usando
modulo 2^32aritmética:i == -ise puede reescribir como2 * i == 0(agregandoien ambos lados), oi << 1 == 0.Esta ecuación tiene dos soluciones de la forma
i == 0 >> 1, a saber,0by se10000000000000000000000000000000bobtiene cambiando en0o1hacia la izquierda.Excluida la solución
i == 0, queda la solucióni == 100000000000000000000000000000000b.fuente
Tal vez no sea demasiado educativo, pero en lugar de pensar que podría ejecutar este código:
para ver que se imprime
infinitamente :)
fuente
<