¿Por qué 11010100 << 1 es igual a 110101000, no 10101000?

40

¿Por qué cuando trato de cambiar bits para 11010100 2 , el resultado es 110101000 2 , no 10101000 2 ?

int a = Integer.parseInt("11010100", 2) << 1;

Intento hacer esto:

int a = (byte)(Integer.parseInt("11010100", 2) << 1);

Pero si el valor de salida es mayor que 128, todo entra en menos, lo cual es lógico. ¿Cómo puedo hacer que ese número de bits no cambie?

Yaroshenko Yaroslav
fuente
44
La aritmética de enteros siempre se realiza en intso longs.
Tom Hawtin - tackline
34
Estás usando enteros, esos son 32 bits de largo. ¿Por qué esperarías que el resultado se truncara a 8 bits?
jhamon
1
byte a = ... lo arreglará.
Perdi Estaquel

Respuestas:

61

Vamos a dar un paso a la vez.

  1. Integer.parseInt("11010100", 2)- este es el valor int 212. Esto es, por cierto, innecesario; simplemente puede escribir: 0b11010100.

  2. 0b11010100 << 1es lo mismo que 0b110101000, y es 424.

  3. A continuación, la echó a un byte: (byte)(0b11010100 << 1). Los bits más allá de los primeros 8 se cortan, lo que deja 0b10101000, que es -88. Menos, sí, porque en Java los bytes están firmados.

  4. Luego, silenciosamente, devuelve este -88 a int, mientras lo asigna a un valor int. Sigue siendo -88, lo que significa que todos los bits superiores son todos 1s.

Por lo tanto, el valor final es -88.

Si desea ver en su 168lugar (que son exactamente los mismos bits, pero se muestran sin signo en lugar de con signo), el truco habitual es usar & 0xFF, que establece todos los bits excepto los primeros 8 a 0, garantizando así un número positivo:

byte b = (byte) (0b11010100 << 1);
System.out.println(b); // -88. It is not possible to print 168 when printing a byte.
int asUnsigned = b & 0xFF;
System.out.println(asUnsigned); // 168.

// or in one go:

System.out.println(((byte) (0b11010100 << 1)) & 0xFF); // 168
rzwitserloot
fuente
19
Está almacenando el valor int a, así que si lo tienes & 0xFF, entonces no necesitas lanzar nada. int a = (0b11010100<< 1) & 0xFF;
Mooing Duck
9

Si desea establecer en 0 todos los bits más altos que los 8 bits inferiores, puede usar Y en cuanto a bits:

int a = (Integer.parseInt("11010100", 2) << 1) & 0xff;
System.out.println (Integer.toString(a,2));

Salida:

10101000
Eran
fuente
6

Intenta algo como esto:

int anInt = Integer.parseInt("11010100", 2) << 1;
int asUnsignedInt= Byte.toUnsignedInt((byte) anInt);

toUnsignedInt se ha introducido en Java SE 8.

Pardo rojizo
fuente