Setelah berkenalan dengan operator bitwise, kita berpindah ke operator yang menggerakkan posisi bit itu sendiri. Operator shift menggeser seluruh pola bit sebuah bilangan ke kiri atau ke kanan sejumlah posisi tertentu — secara praktik, menggeser kiri mengalikan dengan pangkat dua dan menggeser kanan membagi dengan pangkat dua. Java menyediakan tiga operator: << (left shift), >> (signed right shift), dan >>> (unsigned right shift). Perbedaan >> dan >>> hanya terlihat pada bilangan negatif, dan di situlah letak kejutan yang paling sering menangkap pemula — semua angka pada Chapter ini kita verifikasi langsung dari eksekusi nyata.
Tiga Operator Shift #
Operator a << n menggeser bit a sebanyak n posisi ke kiri; posisi kosong di kanan diisi nol, sehingga nilainya menjadi a * 2^n. Operator a >> n menggeser ke kanan dengan menjaga tanda: posisi kosong di kiri diisi salinan bit tanda, sehingga bilangan negatif tetap negatif. Operator a >>> n mengabaikan tanda sepenuhnya — posisi kosong selalu diisi nol, sehingga hasilnya layaknya bilangan tak bertanda (unsigned).
public class GeserBit {
public static void main(String[] args) {
int a = 16;
System.out.println("a = " + a);
System.out.println("a << 2 = " + (a << 2)); // 16 x 2^2 = 64
System.out.println("a >> 2 = " + (a >> 2)); // 16 / 2^2 = 4
int negatif = -8;
System.out.println("negatif = " + negatif);
System.out.println("negatif >> 1 = " + (negatif >> 1)); // -4, tanda dipertahankan
System.out.println("negatif >>> 1 = " + (negatif >>> 1)); // 2147483644, tanda dibuang
System.out.println("1 << 31 = " + (1 << 31)); // meluap batas int
}
}Output yang Dihasilkan:
a = 16
a << 2 = 64
a >> 2 = 4
negatif = -8
negatif >> 1 = -4
negatif >>> 1 = 2147483644
1 << 31 = -2147483648Mari kita telaah baris-baris kode di atas:
- Baris 6 (
a << 2): bit10000(16) bergeser dua posisi menjadi1000000— nilai64, sama dengan16 * 2^2. - Baris 7 (
a >> 2): bit bergeser kembali menghasilkan4, sama dengan16 / 2^2. - Baris 11 (
negatif >> 1):-8dibagi dua menjadi-4— bit tanda ikut disalin sehingga hasil tetap negatif. - Baris 12 (
negatif >>> 1): bit tanda dibuang dan diganti nol, menghasilkan2147483644— bilangan positif raksasa yang muncul dari bilangan negatif kecil. - Baris 14 (
1 << 31): bit tunggal digeser sampai posisi tanda, menghasilkan-2147483648— nilai terkecil yang sanggup ditampungint.
Membaca Bit yang Bergeser #
Angka -8 pada contoh sebelumnya memiliki representasi biner 11111111111111111111111111111000 — 32 bit dengan hampir semuanya bernilai 1. Ketika >> menggeser satu posisi ke kanan, bit tanda 1 disalin ke posisi paling kiri sehingga pola tetap didominasi angka 1 dan hasilnya -4. Ketika >>> menggeser pola yang sama, nol masuk dari kiri sehingga angka 1 di posisi tanda hilang dan hasilnya berubah menjadi positif. Method Integer.toBinaryString memperlihatkan seluruh drama ini bit demi bit.
public class RepresentasiBit {
public static void main(String[] args) {
int nilai = -8;
System.out.println("-8 : " + Integer.toBinaryString(nilai));
System.out.println("-8 >> 1 : " + Integer.toBinaryString(nilai >> 1));
System.out.println("-8 >>> 1 : " + Integer.toBinaryString(nilai >>> 1));
System.out.println("1 << 31 : " + Integer.toBinaryString(1 << 31));
System.out.println("1 << 3 : " + Integer.toBinaryString(1 << 3));
}
}Output yang Dihasilkan:
-8 : 11111111111111111111111111111000
-8 >> 1 : 11111111111111111111111111111100
-8 >>> 1 : 1111111111111111111111111111100
1 << 31 : 10000000000000000000000000000000
1 << 3 : 1000Tiga baris pertama pada output memperlihatkan pergeseran yang sama pada pola bit ...11111000. Hasil -8 >> 1 tetap 32 bit penuh angka 1 di depan, sedangkan -8 >>> 1 hanya menyisakan 31 bit — toBinaryString memang tidak mencetak nol di depan, jadi satu nol terdepan hasil >>> tidak tampil. Baris keempat menegaskan kenapa 1 << 31 bernilai negatif: satu-satunya bit yang hidup tepat berada di posisi bit tanda.
Operator <<, >>, dan >>> melengkapi kotak peralatan level bit kita. Berikutnya kita mundur sejenak ke operator yang paling sering Anda tulis tanpa menyadarinya: operator unary — tanda plus dan minus, komplemen bit, serta pasangan ++ dan -- dengan perbedaan halus postfix melawan prefix.
Referensi #
- Java Language Specification — Bab 15 Expressions
- Class Integer — Java SE 25 API
- Oracle Dev.java — Learn Java
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
GeserBit.java
Unduh berkaspublic class GeserBit {
public static void main(String[] args) {
int a = 16;
System.out.println("a = " + a);
System.out.println("a << 2 = " + (a << 2)); // 16 x 2^2 = 64
System.out.println("a >> 2 = " + (a >> 2)); // 16 / 2^2 = 4
int negatif = -8;
System.out.println("negatif = " + negatif);
System.out.println("negatif >> 1 = " + (negatif >> 1)); // -4, tanda dipertahankan
System.out.println("negatif >>> 1 = " + (negatif >>> 1)); // 2147483644, tanda dibuang
System.out.println("1 << 31 = " + (1 << 31)); // meluap batas int
}
}
RepresentasiBit.java
Unduh berkaspublic class RepresentasiBit {
public static void main(String[] args) {
int nilai = -8;
System.out.println("-8 : " + Integer.toBinaryString(nilai));
System.out.println("-8 >> 1 : " + Integer.toBinaryString(nilai >> 1));
System.out.println("-8 >>> 1 : " + Integer.toBinaryString(nilai >>> 1));
System.out.println("1 << 31 : " + Integer.toBinaryString(1 << 31));
System.out.println("1 << 3 : " + Integer.toBinaryString(1 << 3));
}
}