java - two''s complement calculator
El Java Short más grande(32767) más 1 no se vuelve negativo? (5)
Recientemente aprendí sobre el método del cumplido de los dos para representar números enteros positivos y negativos en el sistema base dos. Luego intenté ver esto en acción usando java con el siguiente código abreviado:
int a=2147483647;
System.out.println("a: "+a);
System.out.println("a+1: "+(a+1));
short b=32767;
System.out.println("b: "+b);
System.out.println("b+1: "+(b+1));
Qué salidas:
a: 2147483647
a + 1: -2147483648
b: 32767
b + 1: 32768
Lo cual me confunde porque creo que b + 1, representado en binario como 011111111111111, se convertiría en 1000000000000000, o en decimal, -32768. ¿Que esta pasando?
Aunque b
es un corto, la expresión (b + 1)
es un int. El operando derecho es un int, el operando izquierdo se promueve a un int, y la expresión es el tipo promocionado de los operandos.
De la especificación del lenguaje Java, 5.6.2. Promoción Numérica Binaria :
La conversión primitiva de ensanche (§5.1.2) se aplica para convertir uno o ambos operandos tal como se especifica en las siguientes reglas:
- Si cualquiera de los dos operandos es del tipo double, el otro se convierte a double.
- De lo contrario, si alguno de los operandos es de tipo float, el otro se convierte en float.
- De lo contrario, si cualquiera de los operandos es de tipo largo, el otro se convierte en largo.
- De lo contrario, ambos operandos se convierten a tipo int.
Tenga en cuenta que esta última promoción se produce incluso si ambos operandos son de tipo abreviado. No puede evitar la promoción a un int con (b + (short) 1)
.
Del 15.18.2. Operadores aditivos (+ y -) para tipos numéricos
El tipo de expresión aditiva en operandos numéricos es el tipo promovido de sus operandos.
Como otros han notado, además promueve los operandos a int
.
Tenga en cuenta que el operador +=
automáticamente realiza la conversión de nuevo a short
:
short b=32767;
System.out.println(b + 1); // 32768, because of integer promotion.
b += 1; // Equivalent to b = (short)(b + 1);
System.out.println(b); // -32768
b++;
/ ++b;
produciría el mismo resultado que b += 1
.
No hay necesidad de confusión, prueba esto:
short b = 32767;
short c = b + 1;
¿Qué obtienes? Bien, usted obtiene:
error: tipos incompatibles: posible conversión con pérdida de int a short short c = b + 1;
Entonces, ¿qué pasa en tu línea? System.out.println("b+1: "+(b+1));
?
Bueno, b+1
es demasiado grande para short
, como dijiste correctamente, pero aquí agregas un int, haciendo que el resultado también sea un int. Y 32768 es un int válido.
Como ya han señalado otros, si lo rechazas explícitamente (short)
obtienes lo que pediste.
Por otro lado, eso no funciona para short c = b + 1;
como aquí el tipo declarado es un corto, mientras que el tipo real es un int
.
short c = (short) (b + 1);
resuelve ese "problema"
doing +
automáticamente promueve short
to int
. Haz esto y verás el desbordamiento.
System.out.println("b+1: "+(short)(b+1)); //-32768
De la especificación del lenguaje Java, 5.6.2. Promoción Numérica Binaria :
La conversión primitiva de ensanche (§5.1.2) se aplica para convertir uno o ambos operandos tal como se especifica en las siguientes reglas:
- Si cualquiera de los dos operandos es del tipo double, el otro se convierte a double.
- De lo contrario, si alguno de los operandos es de tipo float, el otro se convierte en float.
- De lo contrario, si cualquiera de los operandos es de tipo largo, el otro se convierte en largo.
- De lo contrario, ambos operandos se convierten a tipo int .
Observe la última regla, así que, en esencia, eso significa que incluso si ambos son cortos, se promocionarán a int, esto no se puede evitar.
tú podrías:
short b= 32767;
short d= 12;
System.out.println("b+1: "+ (d+b)); // 32779
Y la respuesta todavía sería válida.
1
es un literal int
. Cuando calcula b+1
, de hecho promueve b
a un int
y luego agrega 1
, lo que da como resultado 32768
, que es un valor int
perfectamente legal. Si lo vuelves a short
, verás el desbordamiento que estás esperando ( -32768
):
System.out.println("b+1: " + (short)(b + 1));