Bitwise Operators Trong C/C++ là gì?


bitwise operator là gì

Bitwise Operator là gì?

Trong C, 6 toán tử sau được xếp vào bitwise operators (toán tử vận hành ở cấp bit)
  • & (bitwise AND) lấy hai số làm toán hạng và thực hiện AND lên từng bit của hai số này. Kết quả của AND sẽ chỉ là 1 cả hai bit đều cùng là 1.
  • | (bitwise OR) lấy hai số làm toán hạng và thực hiện OR lên từng bit của hai số này. Kết quả của OR sẽ chỉ là 1 cả hai bit đều cùng là 1.
  • ^ (bitwise XOR) lấy hai số làm toán hạng và thực hiện XOR lên từng bit của hai số này. Kết quả của XOR là 1 nếu hai bit khác nhau.
  • << (left shift) Lấy hai số, chuyển bits của toán hạng đầu tiên sang trái, toán hạng thứ hai quyết định số chỗ trống cần dịch chuyển.
  • >> (right shift)  Lấy hai số, chuyển bits của toán hạng đầu tiên sang phải, toán hạng thứ hai quyết định số chỗ trống cần dịch chuyển.
  • Bitwise Operator trong C
    Bitwsie operator trong C
  • ~ (bitwise NOT) Lấy một số và nghịch đảo tất cả bit của số đó.

Dưới đây là chương trình C ví dụ:
/* C Program to demonstrate use of bitwise operators */
 include
 int main() 
 { 
     unsigned char a = 5, b = 9; // a = 5(00000101), b = 9(00001001) 
     printf("a = %d, b = %d\n", a, b); 
     printf("a&b = %d\n", a&b); // The result is 00000001 
     printf("a|b = %d\n", a|b);  // The result is 00001101 
     printf("a^b = %d\n", a^b); // The result is 00001100 
     printf("~a = %d\n", a = ~a);   // The result is 11111010 
     printf("b<<1 = %d\n", b<<1);  // The result is 00010010       printf("b>>1 = %d\n", b>>1);  // The result is 00000100  
     return 0; 
 } 
Kết quả:
a = 5, b = 9
a&b = 1
a|b = 13
a^b = 12
~a = 250
b<<1 = 18 b>>1 = 4

Dưới đây là một số điều cần lưu ý về toán tử bitwise.

1) Không sử dụng các toán tử left shift và right shift cho số âm. Nếu bất kỳ toán hạng nào là số âm, kết quả sẽ là hành vi không xác định. Ví dụ: kết quả của cả -1 << 1 và 1 << -1 là không xác định. Ngoài ra, nếu số được shift nhiều hơn kích thước của số nguyên đó, hành vi cũng là không xác định. Ví dụ: 1 << 33 không xác định nếu số nguyên được lưu trữ với 32 bit.
2) Toán tử bitwise XOR là toán tử hữu ích nhất cho những buổi phỏng vấn technical. Nó được sử dụng để giải quyết rất nhiều vấn đề. Một ví dụ đơn giản: Được đưa ra một tập hợp các số trong đó tất cả các phần tử xảy ra số lần chẵn trừ một số, tìm số xảy ra lẻ lẻ Vấn đề này có thể được giải quyết một cách hiệu quả bằng cách thực hiện XOR tất cả các số.
// Function to return the only odd occurring element 
 int findOdd(int arr[], int n) { 
    int res = 0, i; 
    for (i = 0; i < n; i++) 
      res ^= arr[i]; 
    return res; 
 } 
 int main(void) { 
    int arr[] = {12, 12, 14, 90, 14, 14, 14}; 
    int n = sizeof(arr)/sizeof(arr[0]); 
    printf ("The odd occurring element is %d ", findOdd(arr, n)); 
    return 0; 
 } 
 // Output: The odd occurring element is 90 
Còn nhiều vấn đề thú vị khác có thể được xử lý với toán tử XOR: Tìm số bị thiếu, hoán đổi hai số mà không sử dụng biến tạm thời, Tìm hai phần tử không lặp lại...
3) Các toán tử bitwise không nên được sử dụng thay cho các toán tử logic. Kết quả của các toán tử logic (&&, || và!) Là 0 hoặc 1, nhưng các toán tử bitwise lại trả về một giá trị nguyên. Ngoài ra, các toán tử logic coi bất kỳ toán hạng khác không là 1. Ví dụ, hãy xem xét chương trình sau, kết quả của & và && là khác nhau cho cùng toán hạng.
int main()  {  int x = 2, y = 5;  (x & y)? printf("True ") : printf("False ");  (x && y)? printf("True ") : printf("False ");  return 0;  }  // Output: False True 
4) Toán tử left-shift và right-shift tương đương với phép nhân và chia cho 2 tương ứng.
Như đã đề cập ở điểm 1, hai toán tử này chỉ làm việc với số dương.
int main() 
 { 
    int x = 19; 
    printf ("x << 1 = %d\n", x << 1);     printf ("x >> 1 = %d\n", x >> 1); 
    return 0; 
 } 
 // Output: 38 9 
5) Toán tử & có thể được sử dụng để nhanh chóng kiểm tra xem một số là số lẻ hay chẵn
Giá trị của biểu thức (x & 1) sẽ khác không chỉ khi x là số lẻ, nếu không giá trị sẽ bằng không.
int main() 
 { 
    int x = 19; 
    (x & 1)? printf("Odd"): printf("Even"); 
    return 0; 
 } 
 // Output: Odd
6) Toán tử ~ nên được sử dụng một cách cẩn thận
Kết quả của toán tử ~ trên một số nhỏ có thể là một số lớn nếu kết quả được lưu trữ trong một biến unsigned. Và kết quả có thể là một số âm nếu kết quả được lưu trữ trong một biến signed (giả sử rằng các số âm được lưu trữ ở dạng bổ sung của 2, trong đó bit ngoài cùng bên trái là sign bit).
// Note that the output of the following program is compiler dependent 
 int main() 
 { 
    unsigned int x = 1; 
    printf("Signed Result %d \n", ~x); 
    printf("Unsigned Result %ud \n", ~x); 
    return 0; 
 } 
 /* Output:  
 Signed Result -2  
 Unsigned Result 4294967294d */

Bạn hãy đọc thêm bài trước để tìm hiểu các dạng operator trong C/C++.

Nhận xét