1. Pergeseran kiri bitwise
Java juga memiliki 3 operator pergeseran bitwise : Jika Anda benar-benar membutuhkannya, Anda dapat dengan mudah menggeser semua bit angka beberapa posisi ke kiri atau kanan.
Untuk menggeser bit angka ke kiri, Anda memerlukan operator bitwise left shift . Begini cara penulisannya:
a << b
Di mana a
angka yang bitnya digeser, dan b
merupakan angka yang menunjukkan berapa kali bit angka digeser a
ke kiri. Selama operasi ini, bit orde rendah yang ditambahkan di sebelah kanan adalah nol.
Contoh:
Contoh | Hasil |
---|---|
|
|
|
|
|
|
|
|
Menggeser satu digit ke kiri memiliki efek yang sama dengan mengalikan angka dengan 2.
Ingin mengalikan angka dengan 16? 16 sama dengan 2 4 . Jadi Anda menggeser angka 4 digit ke kiri
2. Bitwise bergeser ke kanan
Bit juga bisa digeser ke kanan. Untuk melakukan ini, gunakan operator shift kanan bitwise . Begini cara penulisannya:
a >> b
Di mana a
angka yang bitnya digeser, dan b
berapa kali untuk menggeser bit angka a
ke kanan.
Contoh:
Contoh | Hasil |
---|---|
|
|
|
|
|
|
|
|
Menggeser satu digit ke kanan memiliki efek yang sama seperti membagi angka dengan 2.
Selama operasi ini, bit orde tinggi yang ditambahkan di sebelah kiri adalah nol, tetapi tidak selalu !
Bit paling kiri dari angka yang ditandatangani disebut bit tanda : jika angkanya positif, itu adalah 0
; tetapi jika angkanya negatif, bit ini adalah 1
.
Saat menggeser bit angka ke kanan, nilai bit tanda biasanya juga akan bergeser dan tanda angka akan hilang. Oleh karena itu, untuk bilangan negatif (di mana bit paling kiri adalah 1
), bit ini mendapat perlakuan khusus. Saat menggeser bit angka ke kanan, a 0
ditambahkan di sebelah kiri jika bit paling kiri adalah 0
, dan a 1
ditambahkan di sebelah kiri jika bit paling kiri adalah 1
.
Tetapi dalam contoh di atas, tampaknya bukan itu hasilnya. Mengapa? Karena literal bilangan bulat adalah int
s, dan sebenarnya berarti . Artinya, bit paling kiri adalah nol.0b11111111
0b00000000000000000000000011111111
Banyak pemrogram merasa frustrasi dengan perilaku pergeseran kanan ini dan lebih suka angkanya selalu diisi dengan nol. Jadi Java menambahkan operator shift kanan lainnya .
Begini cara penulisannya:
a >>> b
Di mana a
angka yang bitnya digeser, dan b
berapa kali untuk menggeser bit angka a
ke kanan. Operator ini selalu menambahkan nol di sebelah kiri, terlepas dari nilai asli bit tanda angka tersebut a
.
3. Bekerja dengan bendera
Pemrogram menciptakan bidang studi yang hampir seluruhnya baru berdasarkan operasi bitwise dan shift: bekerja dengan bendera.
Ketika komputer memiliki memori yang sangat sedikit, sangat populer untuk menjejalkan banyak informasi ke dalam satu nomor. Sejumlah diperlakukan sebagai larik bit: int adalah 32 bit, dan long adalah 64 bit.
Anda dapat menulis banyak informasi dalam angka seperti itu, terutama jika Anda perlu menyimpan nilai logika ( true
atau false
). Satu long
seperti boolean
array yang terdiri dari 64 elemen. Bit-bit ini disebut flag dan dimanipulasi menggunakan operasi berikut:
-
atur bendera(buat bit tertentu sama dengan
1
) -
atur ulang bendera(buat bit tertentu sama dengan
0
) -
periksa bendera(periksa nilai bit tertentu)
Dan inilah cara melakukannya dengan operator bitwise.
Memasang bendera
Untuk menyetel bit tertentu ke 1
, Anda perlu melakukan operasi bitwise OR antara angka yang bitnya ingin Anda setel dan angka yang dibuat khusus, di mana hanya bit itu 1
.
Misalnya, Anda memiliki nomor 0b00001010
dan Anda perlu menyetel bit ke-5 ke 1
. Dalam hal ini, Anda perlu:
0b00001010 | 0b00010000 = 0b00011010
Jika bit ke-5 sudah disetel ke satu, maka tidak ada yang berubah.
Secara umum, operasi pengaturan bendera dapat ditulis sebagai berikut
a | (1 << b)
Di mana a
angka yang bitnya akan disetel ke 1
. Dan b
apakah posisi bit yang akan diatur. Menggunakan operator shift kiri sangat nyaman di sini, karena Anda dapat langsung mengetahui bagian mana yang sedang kami kerjakan.
Menyetel ulang bendera
Untuk mereset bit tertentu (mis. setel ke 0
) tanpa mengganggu bit lain, Anda perlu melakukan operasi &
antara nomor yang bitnya ingin Anda setel ulang (mis. setel ke 0
) dan nomor yang dibuat khusus, di mana semua bitnya sama dengan 1
kecuali untuk bit yang ingin Anda atur ulang.
Misalnya, Anda memiliki nomor 0b00001010
dan Anda perlu menyetel bit ke-4 ke 0
. Dalam hal ini, Anda perlu:
0b00001010 & 0b11110111 = 0b00000010
Jika bit ke-4 sudah disetel ke nol, maka tidak ada yang berubah.
Secara umum, operasi penyetelan ulang bendera dapat ditulis sebagai berikut
a & ~(1 << b)
Di mana a
angka yang bitnya akan direset ke 0
. Dan b
apakah posisi bit yang akan dibersihkan.
Untuk mendapatkan angka di mana semua bitnya 1
kecuali yang kita inginkan menjadi nol, pertama-tama kita menggeser posisi 1 b ke kiri, lalu menggunakan NOT
operator bitwise untuk membalikkan hasilnya.
Memeriksa bendera
Selain menyetel atau menyetel ulang flag tertentu, kadang-kadang Anda hanya perlu memeriksa apakah flag tertentu sudah disetel, yaitu apakah bit tertentu sama dengan 1
. Ini cukup mudah dilakukan dengan bitwise &
.
Misalnya, Anda perlu memeriksa apakah bit ke-4 disetel ke 1
angka 0b00001010
. Maka Anda perlu melakukan ini:
if ( (0b00001010 & 0b00001000) == 0b00001000 )
Secara umum operasi pengecekan bendera dapat ditulis sebagai berikut
(a & (1 << b)) == (1 << b)
Di mana a
nomor yang bitnya sedang diperiksa. Dan b
apakah posisi bit yang akan diperiksa.
4. Enkripsi
Operasi bitwise XOR
sering digunakan oleh programmer untuk enkripsi sederhana. Secara umum, enkripsi seperti ini terlihat seperti ini:
result = number ^ password;
Dimana number
data yang ingin kita enkripsi, password
merupakan nomor khusus yang digunakan sebagai “password” untuk data tersebut, dan result
merupakan nomor yang dienkripsi.
number == (number ^ password) ^ password;
Hal penting di sini adalah ketika XOR
operator diterapkan ke nomor dua kali, itu menghasilkan nomor asli, terlepas dari "kata sandi".
Untuk memulihkan number
dari encrypted result
, Anda hanya perlu melakukan operasi lagi:
original number = result ^ password;
Contoh:
class Solution
{
public static int[] encrypt(int[] data, int password)
{
int[] result = new int[data.length];
for (int i = 0; i < data.length; i++)
result[i] = data[i] ^ password;
return result;
}
public static void main(String[] args)
{
int[] data = {1, 3, 5, 7, 9, 11};
int password = 199;
// Encrypt the array of data
int[] encrypted = encrypt(data, password);
System.out.println(Arrays.toString(encrypted));
// Decrypt the array of data
int[] decrypted = encrypt(encrypted, password);
System.out.println(Arrays.toString(decrypted));
}
}