Mengapa 11010100 << 1 sama dengan 110101000, bukan 10101000?

40

Mengapa ketika saya mencoba menggeser bit untuk 11010100 2 , hasilnya adalah 110101000 2 , bukan 10101000 2 .

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

Saya mencoba melakukan ini:

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

Tetapi jika nilai output lebih besar dari 128, semuanya menjadi minus, yang logis. Bagaimana saya bisa membuat jumlah bit tidak berubah?

Yaroshenko Yaroslav
sumber
4
Aritmatika integer selalu dilakukan pada ints atau longs.
Tom Hawtin - tackline
34
Anda menggunakan integer, panjangnya 32 bit. Mengapa Anda berharap hasilnya akan terpotong menjadi 8 bit?
jhamon
1
byte a = ... akan memperbaikinya.
Perdi Estaquel

Jawaban:

61

Mari kita selangkah demi selangkah.

  1. Integer.parseInt("11010100", 2)- ini adalah nilai int 212. Ini, omong-omong, tidak perlu; Anda hanya dapat menulis: 0b11010100.

  2. 0b11010100 << 1sama dengan 0b110101000, dan 424.

  3. Anda kemudian melemparkannya ke byte: (byte)(0b11010100 << 1). Bit di luar 8 pertama semuanya dipotong, yang meninggalkan 0b10101000, yaitu -88. Minus, ya, karena dalam byte java ditandatangani.

  4. Anda kemudian secara diam-diam melemparkan -88 ini kembali ke int, saat Anda menetapkannya ke nilai int. Tetap -88, yang berarti semua bit teratas semua 1s.

Oleh karena itu, nilai akhirnya adalah -88.

Jika Anda ingin melihat 168sebagai gantinya (yang merupakan bit yang sama persis, tetapi ditampilkan tanpa tanda tangan alih-alih ditandatangani), trik yang biasa adalah dengan menggunakan & 0xFF, yang menetapkan semua bit kecuali yang pertama menjadi 8, sehingga menjamin angka positif:

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
sumber
19
Dia menyimpan nilai int a, jadi jika Anda memiliki & 0xFF, maka Anda tidak perlu membuang sama sekali. int a = (0b11010100<< 1) & 0xFF;
Mooing Duck
9

Jika Anda ingin mengatur ke 0 semua bit lebih tinggi dari 8 bit terbawah, Anda bisa menggunakan bit-wise AND:

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

Keluaran:

10101000
Eran
sumber
6

Coba sesuatu seperti ini:

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

toUnsignedInt telah diperkenalkan di Java SE 8.

Puce
sumber