Tengo la siguiente if
condición.
if (i == -i && i != 0)
¿Qué valor de i
devolverá true
para esta condición en Java?
No puedo pensar en tal valor de i
considerar 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.0
también es== 0
if(i && i == -i)
Respuestas:
El único
int
valor 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_VALUE
esLa toma del valor negativo se realiza intercambiando primero
0
y1
, 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_Value
si lo almacena en unlong
variable.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
0
valores 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:0
yInteger.MIN_VALUE
. Pori != 0
en tu si, soloMIN_VALUE
queda.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 aint
para 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_VALUE
es igual a-2^31
o-2147483648
yInteger.MAX_VALUE
es igual a2^31-1
o2147483647
.-Integer.MIN_VALUE
es2^31
, que ahora es demasiado grande para un Integer (ya que es pasadoMAX_VALUE
), lo que provoca un desbordamiento de Integer,Integer.MIN_VALUE
volviéndolo de nuevo. Es el único entero que hace esto, ya queMIN_VALUE
es el único número sin equivalente negativo aparte de 0.fuente
2147483648
puede 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^32
aritmética:i == -i
se puede reescribir como2 * i == 0
(agregandoi
en ambos lados), oi << 1 == 0
.Esta ecuación tiene dos soluciones de la forma
i == 0 >> 1
, a saber,0b
y se10000000000000000000000000000000b
obtiene cambiando en0
o1
hacia 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
<