"Hai, Amigo!"

"Saya juga ingin bercakap tentang bitmasks dan XOR."

"Anda sudah tahu bahawa nombor terdiri daripada bit dan anda boleh melakukan pelbagai operasi pada bit ini. Bitmask ialah perwakilan beberapa nilai logik yang berbeza (nilai benar/salah) sebagai integer tunggal. Dalam kes ini, setiap nilai boolean sepadan dengan sedikit. Begini cara ini boleh dilakukan:"

"Perwakilan binari kuasa dua (1, 2, 4, 8, 16, 32, ...) hanya melibatkan penetapan satu bit:"

Nombor Perwakilan binari
1 0000 0001
2 0000 0010
4 0000 0100
8 0000 1000
16 0001 0000
19 (bukan kuasa dua) 0001 0011
31 (bukan kuasa dua) 0001 1111

"Jadi, mana-mana integer boleh dianggap sebagai tatasusunan bit atau tatasusunan nilai boolean."

"Begini cara anda boleh menyimpan nilai boolean yang berbeza dalam satu nombor:"

Nilai Boolean
boolean a = true;
boolean b = false;
boolean c = true;
boolean d = false;
Nilai dimasukkan ke dalam satu nombor:
int result = 0;
 if (a) result += 1; // 1 == 20 — bit 0
 if (b) result += 2; // 2 == 21 — bit 1
 if (c) result += 4; // 4 == 22 — bit 2
 if (d) result += 8; // 8 == 23 — bit 3

"Kini setiap bit ialah 1 jika pembolehubah boolean yang sepadan adalah benar."

Dalam kes kami, pembolehubah a dan c adalah benar, jadi hasilnya adalah sama dengan 1+4 == 5

0000 0101
0000 dcba

"Saya rasa saya tahu apa yang berlaku."

"Baiklah, jika anda faham, mari kita teruskan."

"Int mempunyai 32 bit. Satu daripadanya digunakan untuk tanda nombor, dan 31 lagi boleh digunakan untuk menyimpan nilai 31 pembolehubah boolean."

"A long mempunyai 64 bit di mana kita boleh menyimpan 63 pembolehubah boolean."

"Ya."

"Berpuluh-puluh pembolehubah bersesak dalam satu nombor. Itu agak sedikit."

"Tetapi di mana ini digunakan?"

"Terutamanya dalam situasi di mana anda perlu menyimpan banyak maklumat tentang objek. Apabila anda menyimpan banyak maklumat tentang objek, sentiasa terdapat beberapa dozen pembolehubah boolean. "Dengan pendekatan ini, semuanya mudah disimpan dalam satu nombor ."

"Dengan penekanan pada perkataan 'disimpan'. Kerana sebenarnya menggunakan nombor itu tidak begitu mudah."

"Omong-omong, itu sahaja yang saya ingin tanya. Bagaimanakah cara kita mengekstrak nilai boolean daripada nombor itu?"

"Ia tidak rumit sama sekali. Katakan anda perlu menentukan sama ada bit 6 ditetapkan kepada 1 (2 kepada kuasa lima ialah 32). Kita boleh menyemak seperti ini:"

Gabungkan nombor menjadi satu:
int a = 32; // 25 == 0010 0000
int b = 8; // 23 == 0000 1000
int c = 2; // 21 == 0000 0010

int result = a + b + c; // 32 + 8 + 2 == 42 == 0010 1010
Ekstrak nilai dengan menyemak bit tertentu:
int a = result & 32; // 0010 1010 & 0010 0000 = 0010 0000
int b = result & 8; // 0010 1010 & 0000 1000 = 0000 1000
int c = result & 2; // 0010 1010 & 0000 0010 = 0000 0010

"Oleh itu, bekerja dengan bitmasks melibatkan tiga operasi:"

1)  Tetapkan bit tertentu kepada 0

2)  Tetapkan bit tertentu kepada 1

3)  Semak nilai bit tertentu.

"Ambil bit 6, sebagai contoh."

"Bagaimana anda menetapkan bit 6 kepada 1?"

Kod Penerangan
result = result | 01000000;
result |= 01000000;
Bagaimana anda menetapkan bit 6 kepada 1?
result = result & 10111111;
result &= 10111111;
Bagaimanakah anda menetapkan bit 6 kepada 0?
c = result & 01000000;
Bagaimanakah anda mendapatkan nilai bit 6?

"Itu sangat luar biasa, tetapi tidak sukar. Lelaki, sekarang saya seorang pengaturcara panas."

"Dan satu lagi petua kecil tentang cara mudah mendapatkan nombor dengan bit tertentu ditetapkan kepada 0 atau 1: 01000000 atau 10111111."

Untuk ini, kami mempunyai  operator >> dan  << .

"1 ialah 2 kepada kuasa sifar. Dalam erti kata lain, nombor dengan bit 0 ditetapkan kepada 1. Kami memerlukan nombor dengan set bit 6."

int c = 1 << 6; // 0000 0001 << 6 == 0100 0000 == 64

"Sejuk! Itu sangat membantu untuk kes sebegini."

"Tetapi bagaimana jika saya memerlukan nombor di mana setiap bit ditetapkan kepada 1 kecuali satu bit tertentu ditetapkan kepada 0?"

"Itu juga tidak sukar:"

int d = ~(1 << 6); // ~0100 0000 == 10111111

"Dengan kata lain, semuanya sangat mudah:"

Kod Penerangan
result = result | (1 << 6);
result |= (1 << 6);
Bagaimana anda menetapkan bit 6 kepada 1?
result = result & ~(1 << 6);
result &= ~(1 << 6);
Bagaimanakah anda menetapkan bit 6 kepada 0?
c = result & (1 << 6);
Bagaimanakah anda mendapatkan nilai bit 6?

"Nampak tak susah sangat. Tapi saya tak ingat langsung."

"Tetapi, jika anda menemui ungkapan yang menakutkan seperti "hasil &= ~(1 << 6)" dalam kod orang lain, anda akan tahu bahawa seseorang ini hanya bekerja dengan bitmask."

"Dan jika anda sering menemuinya, maka ia akan mengingati dirinya sendiri untuk anda."

"Ingat sendiri... Bunyinya bagus. Terima kasih atas pengajarannya."