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));