Apa itu Bit Masking?

191

Saya cukup baru untuk pemrograman C, dan saya menemukan sedikit masking. Dapatkah seseorang menjelaskan kepada saya konsep dan fungsi umum dari bit masking? Contohnya sangat dihargai.

Mr.Z
sumber
1
Apakah Anda memahami operator bitwise seperti & | ^ dll dan logika Boolean secara umum? Penjelasan tentang operasi mask akan membutuhkan ini.
Paul R
1
Ya, saya mengerti operator bitwise, dan logika boolean
Mr.Z
2
Saya tahu tautan tidak boleh diposting, tetapi penjelasan wikipedia sangat bagus: en.wikipedia.org/wiki/Mask_(computing)
pevik
2
@pevik ok untuk memposting tautan tetapi dengan beberapa uraian sehingga jika tautan mati suatu hari nanti, pos tersebut masih dapat melayani tujuannya untuk menjawab. juga tautan tidak boleh untuk tujuan promosi belaka.
Dexter

Jawaban:

246

Topeng menentukan bit mana yang ingin Anda simpan, dan bit mana yang ingin Anda hapus.

Masking adalah tindakan menerapkan topeng pada suatu nilai. Ini dicapai dengan melakukan:

  • Bitwise ANDing untuk mengekstrak subset bit dalam nilai
  • Bitwise ORing untuk mengatur subset bit dalam nilai
  • Bitwise XORing untuk mengaktifkan subset bit dalam nilai

Di bawah ini adalah contoh mengekstraksi subset bit dalam nilai:

Mask:   00001111b
Value:  01010101b

Menerapkan mask ke nilai berarti kita ingin menghapus 4 bit pertama (lebih tinggi), dan menyimpan 4 bit terakhir (lebih rendah). Jadi kami telah mengekstraksi 4 bit yang lebih rendah. Hasilnya adalah:

Mask:   00001111b
Value:  01010101b
Result: 00000101b

Masking diimplementasikan menggunakan AND, jadi di C kita mendapatkan:

uint8_t stuff(...) {
  uint8_t mask = 0x0f;   // 00001111b
  uint8_t value = 0x55;  // 01010101b
  return mask & value;
}

Berikut ini adalah kasus penggunaan yang cukup umum: Mengekstrak byte individual dari kata yang lebih besar. Kami mendefinisikan bit orde tinggi dalam kata sebagai byte pertama. Kami menggunakan dua operator untuk ini &,, dan >>(bergeser ke kanan). Ini adalah bagaimana kita dapat mengekstrak empat byte dari integer 32-bit:

void more_stuff(uint32_t value) {             // Example value: 0x01020304
    uint32_t byte1 = (value >> 24);           // 0x01020304 >> 24 is 0x01 so
                                              // no masking is necessary
    uint32_t byte2 = (value >> 16) & 0xff;    // 0x01020304 >> 16 is 0x0102 so
                                              // we must mask to get 0x02
    uint32_t byte3 = (value >> 8)  & 0xff;    // 0x01020304 >> 8 is 0x010203 so
                                              // we must mask to get 0x03
    uint32_t byte4 = value & 0xff;            // here we only mask, no shifting
                                              // is necessary
    ...
}

Perhatikan bahwa Anda dapat mengubah urutan operator di atas, pertama-tama Anda bisa melakukan mask, kemudian shift. Hasilnya sama, tetapi sekarang Anda harus menggunakan topeng yang berbeda:

uint32_t byte3 = (value & 0xff00) >> 8;
pengguna239558
sumber
5
Jawaban yang bagus tetapi masking juga dapat diterapkan untuk mengatur atau mengganti bit tertentu dengan operasi OR atau XOR dan mask yang sesuai.
Paul R
@ user239558 terima kasih untuk contoh dan sintaks yang tepat. @ Paul R. Apakah saya hanya mengatakan topeng DAN nilai dalam contoh yang disediakan oleh user239558
Mr.Z
@ Mr.Z: dalam bahasa C, C ++ dan yang terkait, Anda akan menggunakan operator bitwise AND , yang ditulis sebagai &.
Paul R
@ Mr.Z Misalnya: jelas salah satu byte dari uint32_t dengan masking isi pergi: #define MASK 0x000000FF .... my_uint32_t &= ~MASK.
Lundin
yang bliteral untuk menunjukkan biner tidak didukung oleh semua kompiler, benar?
Ungeheuer
76

Masking berarti menjaga / mengubah / menghapus bagian informasi yang diinginkan. Mari kita lihat operasi masking gambar; seperti- operasi masking ini menghilangkan segala sesuatu yang bukan kulit

masukkan deskripsi gambar di sini

Kami sedang melakukan DAN operasi dalam contoh ini. Ada juga operator masking lainnya- OR , XOR .


Masking Bit berarti memaksakan mask over bits. Inilah sedikit penutup dengan DAN -

     1 1 1 0 1 1 0 1   [input]
(&)  0 0 1 1 1 1 0 0    [mask]
------------------------------
     0 0 1 0 1 1 0 0  [output]

Jadi, hanya 4 bit tengah (seperti bit ini 1dalam topeng ini) yang tersisa.

Mari kita lihat ini dengan XOR -

     1 1 1 0 1 1 0 1   [input]
(^)  0 0 1 1 1 1 0 0    [mask]
------------------------------
     1 1 0 1 0 0 0 1  [output]

Sekarang, 4 bit tengah dibalik ( 1menjadi 0, 0menjadi 1).


Jadi, menggunakan bit-mask kita bisa mengakses bit-bit [ contoh ]. Terkadang, teknik ini juga dapat digunakan untuk meningkatkan kinerja. Ambil ini sebagai contoh-

bool isOdd(int i) {
    return i%2;
}

Fungsi ini memberi tahu apakah bilangan bulat ganjil / genap. Kita dapat mencapai hasil yang sama dengan efisiensi lebih banyak menggunakan bit-mask-

bool isOdd(int i) {
    return i&1;
}

Penjelasan Singkat : Jika bit paling tidak signifikan dari angka biner adalah 1itu aneh; karena 0itu akan genap. Jadi, dengan melakukan AND with 1kami menghapus semua bit lain kecuali untuk bit yang paling signifikan yaitu:

     55  ->  0 0 1 1 0 1 1 1   [input]
(&)   1  ->  0 0 0 0 0 0 0 1    [mask]
---------------------------------------
      1  <-  0 0 0 0 0 0 0 1  [output]
Minhas Kamal
sumber
1
Juga, untuk mengkonversi bilangan bulat ke no aneh. jika itu bilangan genap: i = i | 1. Ini sangat berguna ketika kita mencoba untuk menghasilkan urutan seperti 1, 3, 5, ..., 2, 4, 6, ...
Harshit Sharma
Anda juga dapat menggunakan operasi berikut untuk menemukan nomor dengan hanya bit paling tidak signifikan dari integer: lsb = i & -i
Harshit Sharma