two java binary short twos-complement

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