Bit Masking là gì?


191

Tôi còn khá mới với lập trình C, và tôi đã gặp phải mặt nạ bit. Ai đó có thể giải thích cho tôi khái niệm và chức năng chung của mặt nạ bit? Ví dụ được nhiều đánh giá cao.


1
Bạn có hiểu các toán tử bitwise như & | ^ vv và logic Boolean nói chung? Bất kỳ lời giải thích về hoạt động mặt nạ sẽ yêu cầu này.
Paul R

1
Có, tôi hiểu về các toán tử bitwise và logic boolean
Mr.Z

2
Tôi biết các liên kết không nên được đăng, nhưng giải thích wikipedia là tuyệt vời: en.wikipedia.org/wiki/Mask_(computing)
pevik

2
@pevik bạn có thể đăng liên kết nhưng với một số mô tả để nếu liên kết chết vào một ngày nào đó, bài đăng vẫn có thể phục vụ mục đích trả lời của nó. liên kết cũng không nên chỉ cho mục đích quảng cáo.
Dexter

Câu trả lời:


243

Một mặt nạ xác định bit nào bạn muốn giữ và bit nào bạn muốn xóa.

Đắp mặt nạ là hành động áp dụng mặt nạ cho một giá trị. Điều này được thực hiện bằng cách làm:

  • Bitwise ANDing để trích xuất một tập hợp con của các bit trong giá trị
  • Bitwise ORing để đặt tập hợp con của các bit trong giá trị
  • Bitwise XORing để chuyển một tập hợp con của các bit trong giá trị

Dưới đây là một ví dụ về trích xuất một tập hợp con của các bit trong giá trị:

Mask:   00001111b
Value:  01010101b

Áp dụng mặt nạ cho giá trị có nghĩa là chúng tôi muốn xóa 4 bit đầu tiên (cao hơn) và giữ 4 bit cuối cùng (thấp hơn). Vì vậy, chúng tôi đã trích xuất 4 bit thấp hơn. Kết quả là:

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

Tạo mặt nạ được thực hiện bằng AND, vì vậy trong C chúng ta nhận được:

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

Đây là một trường hợp sử dụng khá phổ biến: Trích xuất từng byte riêng lẻ từ một từ lớn hơn. Chúng tôi định nghĩa các bit thứ tự cao trong từ là byte đầu tiên. Chúng tôi sử dụng hai toán tử cho việc này &>>(shift phải). Đây là cách chúng ta có thể trích xuất bốn byte từ số nguyên 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
    ...
}

Lưu ý rằng bạn có thể chuyển đổi thứ tự của các toán tử ở trên, trước tiên bạn có thể thực hiện mặt nạ, sau đó thay đổi. Kết quả là như nhau, nhưng bây giờ bạn sẽ phải sử dụng một mặt nạ khác:

uint32_t byte3 = (value & 0xff00) >> 8;

5
Câu trả lời tốt nhưng mặt nạ cũng có thể được áp dụng để thiết lập hoặc chuyển đổi các bit cụ thể bằng các thao tác OR hoặc XOR và mặt nạ phù hợp.
Paul R

@ user239558 cảm ơn vì ví dụ và cú pháp thích hợp. @ Paul R. Tôi chỉ đơn giản nói mặt nạ VÀ giá trị trong ví dụ được cung cấp bởi user239558
Mr.Z

@ Mr.Z: trong C, C ++ và các ngôn ngữ liên quan, bạn sẽ sử dụng toán tử bitwise AND , được viết là &.
Paul R

@ Mr.Z Ví dụ: xóa một byte của uint32_t bằng cách che giấu nội dung đi : #define MASK 0x000000FF .... my_uint32_t &= ~MASK.
Lundin

các bnghĩa đen để chỉ nhị phân không được hỗ trợ bởi tất cả các trình biên dịch, có đúng không?
Ungeheuer

76

Mặt nạ có nghĩa là giữ / thay đổi / loại bỏ một phần thông tin mong muốn. Cho phép xem một hoạt động che giấu hình ảnh; giống như- hoạt động mặt nạ này là loại bỏ bất kỳ thứ gì không phải da-

nhập mô tả hình ảnh ở đây

Chúng tôi đang làm hoạt động trong ví dụ này. Ngoài ra còn có các toán tử mặt nạ khác - HOẶC , XOR .


Bit-Masking có nghĩa là áp đặt mặt nạ trên bit. Đây là một mặt nạ bit với AND -

     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]

Vì vậy, chỉ còn lại 4 bit ở giữa (vì các bit này nằm 1trong mặt nạ này).

Hãy xem điều này với 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]

Bây giờ, 4 bit ở giữa được lật ( 1trở thành 0, 0trở thành 1).


Vì vậy, bằng cách sử dụng mặt nạ bit, chúng ta có thể truy cập các bit riêng lẻ [ ví dụ ]. Đôi khi, kỹ thuật này cũng có thể được sử dụng để cải thiện hiệu suất. Lấy ví dụ này-

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

Hàm này cho biết nếu một số nguyên là lẻ / chẵn. Chúng ta có thể đạt được kết quả tương tự với hiệu quả cao hơn bằng cách sử dụng mặt nạ bit-

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

Giải thích ngắn : Nếu bit có ý nghĩa nhỏ nhất của số nhị phân 1thì đó là số lẻ; cho 0nó sẽ được thậm chí Vì vậy, bằng cách thực hiện AND với 1chúng tôi sẽ loại bỏ tất cả các bit khác ngoại trừ bit có ý nghĩa nhỏ nhất, ví dụ:

     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]

1
Ngoài ra, để chuyển đổi một số nguyên thành số lẻ. nếu nó là số chẵn: i = i | 1. Điều này rất hữu ích khi chúng tôi đang cố gắng tạo ra một chuỗi như 1, 3, 5, ..., 2, 4, 6, ...
Harshit Sharma

Bạn cũng có thể sử dụng thao tác sau để tìm số chỉ có bit có ý nghĩa nhỏ nhất từ ​​một số nguyên: lsb = i & -i
Harshit Sharma
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.