Setelah mengenal bitwise pada bab sebelumnya, kini kita melihat sepasang operator yang menggeser seluruh pola bit, bukan membandingkannya. Operator shift sering muncul pada kode flag, encoding, dan perhitungan pangkat dua yang butuh kecepatan tinggi. Karena operator bekerja pada representasi biner, kita kembali memakai Convert.ToString(nilai, 2) untuk memeriksa hasilnya.

Dua Operator Shift #

OperatorNamaEfek pada bilangan positif
x << nLeft shiftMenggeser bit x ke kiri sebanyak n posisi; ekuivalen x * 2^n
x >> nRight shiftMenggeser bit x ke kanan sebanyak n posisi; ekuivalen x / 2^n dengan pembulatan ke bawah

Mekanismenya sederhana. Pada left shift, setiap bit berpindah ke kiri; bit yang keluar dari batas kiri ditinggalkan dan sisi kanan diisi 0. Pada right shift bilangan positif, setiap bit berpindah ke kanan dan sisi kiri diisi 0; bit yang keluar dari kanan ditinggalkan.

Contoh dan Bedah Baris #

csharp
int lampu = 0b0001_0010;   // 18

Console.WriteLine($"nilai awal : {Convert.ToString(lampu, 2).PadLeft(8, '0')} ({lampu})");
Console.WriteLine($"lampu << 2 : {Convert.ToString(lampu << 2, 2).PadLeft(8, '0')} ({lampu << 2})");
Console.WriteLine($"lampu >> 2 : {Convert.ToString(lampu >> 2, 2).PadLeft(8, '0')} ({lampu >> 2})");

Console.WriteLine(1 << 10);
Console.WriteLine(1024 >> 3);

Output yang Dihasilkan:

text
nilai awal : 00010010 (18)
lampu << 2 : 01001000 (72)
lampu >> 2 : 00000100 (4)
1024
128

Mari kita telaah baris demi baris:

  1. Baris 1 (lampu): Variabel menyimpan 18 dengan penulisan biner 0001_0010; garis bawah hanya pemisah keterbacaan.
  2. Baris 3 (lampu << 2): Seluruh bit bergeser dua posisi ke kiri, sisi kanan diisi 00; pola menjadi 01001000 bernilai 72, sama dengan 18 * 4.
  3. Baris 4 (lampu >> 2): Bit bergeser dua posisi ke kanan, dua bit terakhir (10) ditinggalkan; pola menjadi 00000100 bernilai 4, sama dengan 18 / 4 yang dibulatkan ke bawah.
  4. Baris 6 (1 << 10): Satu bit digeser sepuluh posisi menghasilkan 1024, yaitu 2 pangkat 10.
  5. Baris 7 (1024 >> 3): Geser kanan tiga posisi membagi 1024 dengan 8, hasilnya 128.

Perilaku pada Bilangan Negatif #

Bilangan negatif disimpan dengan bit tertinggi bernilai 1 sebagai penanda tanda. Right shift pada bilangan negatif mempertahankan bit penanda itu (disebut arithmetic shift), sehingga tanda tetap negatif; left shift tetap mengisi sisi kanan dengan 0:

csharp
Console.WriteLine(-8 >> 1);
Console.WriteLine(-8 << 1);

Output yang Dihasilkan:

text
-4
-16

Nilai -8 >> 1 menjadi -4 karena geser kanan membagi 8 dengan 2 tanpa mengubah tandanya, sedangkan -8 << 1 menjadi -16 karena geser kiri mengalikan dengan 2. Hubungan pangkat dua ini berlaku sama untuk bilangan negatif maupun positif.

Nilai penggeser tidak harus konstanta; expression x << n menerima variabel n apa pun bertipe int. Meski demikian, untuk keterbacaan kebanyakan kode memakai angka tetap yang maksudnya langsung terlihat.