java - two's complement calculator binary




El Java Short más grande(32767) más 1 no se vuelve negativo? (4)

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 .


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




twos-complement