#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;
}