#include <stdio.h>
int main() {
// 位操作符
// 操作符 說明
// ~ 按位取反
// << 左移
// >> 右移
// <<= 左移並賦值
// >>= 右移並賦值
// & 按位與
// ^ 按位異或
// | 按位或
// &= 按位與賦值
// ^= 按位異或賦值
// |= 按位或賦值
// 按位取反
// 假如有一個二進制數: 10100111 按位取反就是: 01011000
// unsigned char a = 181; a 的二進制數爲 1011 0101用計算器就行
// 取反結果就是0100 1010 轉十進制就是74
unsigned char a = 181;
unsigned char b = ~a;
printf("b = %u \n", b);
// 不能直接printf("%u \n", ~181); 181是int類型
printf("%u \n", (unsigned char) ~181);
// 左移 右移
// 假如unsigned char b = 171;的二進制數爲 1010 1011
// 右移 b >> 1 二進制:1010 1011 >> 1 等於 0101 0101 從左向右移,右邊被移掉的舍掉, 高位用0補充
// 右移 b >> 3 二進制:1010 1011 >> 3 等於 0001 0101 從左向右移,右邊被移掉的舍掉, 高位用0補充
// 右移 b >> 8 二進制:1010 1011 >> 8 等於 0000 0000 從左向右移,右邊被移掉的舍掉, 高位用0補充
printf("左移 右移\n");
printf("%u \n", (unsigned char)(171 >> 1)); // 85
printf("%u \n", (unsigned char)(171 >> 3)); // 21
printf("%u \n", (unsigned char)(171 >> 8)); // 0
printf("\n");
// 按位與, 按位或, 按位異或
// 0011 0111 = 0x37
// 0101 1001 = 0x59
// 0x37與0x59每個bit位做比較
// 0x37 & 0x59 = ? 兩位需要爲真才爲真 = 1(按位與)
// 1001 0001
// 0x37 | 0x59 = ? 兩位其中有一個爲真就是爲真 = 1(按位或)
// 0111 1111
// 0x37 ^ 0x59 = ? 兩個都爲真那就爲假,其中一個爲真一個爲假那麼爲真,兩個都爲假就爲假(按位異或)
// 0110 1110
printf("按位與, 按位或, 按位異或\n");
printf("%u \n", (unsigned char)(0x37 & 0x59));
printf("%u \n", (unsigned char)(0x37 | 0x59));
printf("%u \n", (unsigned char)(0x37 ^ 0x59));
printf("\n");
char buf[] = "A2";
unsigned int n1 = (buf[0] - 'A') + 10;
unsigned int n2 = (buf[1] - '0');
unsigned int result = n1 * 16 + n2;
// 向左位移四位相當於* 16, 位移要比* /運算速度快
unsigned int result2 = (n1 << 4) + n2;
printf("%d \n", result); // 162
printf("%d \n", result2); // 162
// 單bit操作(常用)
unsigned char u = 181;
// 1011 0101
u &= ~(u << 5);
// 1010 0000 (u << 5) = 160
// 0101 1111 ~(u << 5) = 95
// 0001 0101 u &= ~(u << 5) = 21
printf("%u \n ", u);
// 假如修改第七個bit位爲1,首先我們未知本身是0還是1
// 1011 0101 | 0100 000 按位或,只要一個爲真那就是爲真
// 1111 0101
// 判斷一個bit位是爲1還是爲0,假設我們要判斷第五個bit位
// 用按位與, 只有都爲真的情況下才爲真
// 1011 0101 & 0001 0000
return 0;
}