Perché 11010100 << 1 equivale a 110101000, non 10101000?


40

Perché quando provo a spostare i bit per 11010100 2 , il risultato è 110101000 2 , non 10101000 2 .

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

Provo a fare questo:

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

Ma se il valore di output è maggiore di 128, tutto diventa meno, il che è logico. Come posso fare per non cambiare quel numero di bit?


4
L'aritmetica intera viene sempre eseguita su ints o longs.
Tom Hawtin - affronta il

34
Stai utilizzando numeri interi, lunghi 32 bit. Perché dovresti aspettarti che il risultato venga troncato a 8 bit?
jhamon,

1
byte a = ... lo risolverà.
Perdi Estaquel,

Risposte:


61

Facciamo un passo alla volta.

  1. Integer.parseInt("11010100", 2)- questo è il valore int 212. A proposito, questo è inutile; si può solo scrivere: 0b11010100.

  2. 0b11010100 << 1è uguale a 0b110101000ed è 424.

  3. È quindi lanci a un byte: (byte)(0b11010100 << 1). I bit oltre i primi 8 vengono tutti eliminati, il che lascia 0b10101000, che è -88. Meno, sì, perché in java i byte sono firmati.

  4. Quindi esegui il backup silenzioso di questo -88 su int, mentre lo assegni a un valore int. Resta -88, il che significa che tutti i bit superiori sono tutti 1s.

Quindi, il valore finale è -88.

Se invece vuoi vedere 168(che è esattamente gli stessi bit, ma mostrato senza segno anziché con segno), il solito trucco è usare & 0xFF, che imposta tutti i bit tranne i primi 8 a 0, garantendo così un numero 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

19
Sta memorizzando il valore int a, quindi se ce l' & 0xFFhai, non è necessario lanciarlo affatto. int a = (0b11010100<< 1) & 0xFF;
Mooing Duck

9

Se si desidera impostare 0 su tutti i bit più alti degli 8 bit inferiori, è possibile utilizzare AND bit-saggio:

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

Produzione:

10101000

6

Prova qualcosa del genere:

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

toUnsignedInt è stato introdotto in Java SE 8.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.