&按位与
int result = 21 & 18;
printf("%d",result);
/*
21: 0000 0000 0000 0000 0000 0000 0001 0101
18: 0000 0000 0000 0000 0000 0000 0001 0010
16: 0000 0000 0000 0000 0000 0000 0001 0000 按位与结果
*/
常见按位与应用
(a >> i) & 1 //判断a的第i位是0还是1,表达式返回值就是第i位,和1按位与就相当于和全0最后一位为1的二进制做与运算。
a & 0xffffff00 //a低8位置0,其他位保持不变(可设置任意位)。
a & 0x80 //判断a的第7位(地址从0开始),是否为1,为1则表达式等于0x80。
|按位或
int result = 21 | 18;
printf("%d",result);
/*
21: 0000 0000 0000 0000 0000 0000 0001 0101
18: 0000 0000 0000 0000 0000 0000 0001 0010
23: 0000 0000 0000 0000 0000 0000 0001 0111 按位或结果
*/
常见按位或应用
a | 0x000000ff //a低8位置1,其他位保持不变(可设置任意位)。
^按位异或
//异或:二进制位不同时为1
int result = 21 ^ 18;
printf("%d",result);
/*
21: 0000 0000 0000 0000 0000 0000 0001 0101
18: 0000 0000 0000 0000 0000 0000 0001 0010
7: 0000 0000 0000 0000 0000 0000 0000 0111 按位异或结果
*/
常见按位异或应用
a ^ 0x000000ff //把低8位取反,其他位不变(可设置任意位)。
a = a ^ b; b = b ^ a; a = a ^ b; //可以实现不通过临时变量交换两个变量的值。
~按位非
int result = ~21;
printf("%d",result);
/*
21: 0000 0000 0000 0000 0000 0000 0001 0101
-22: 1111 1111 1111 1111 1111 1111 1110 1010 按位非结果(补码表示)
*/
<<左移运算符:左移时高位丢弃,低位补0,实际上,左移一位,就等于乘以2,左移n位,就等于乘以2^n,比乘法快。
>>右移运算符:右移时低位丢弃,高位根据符号来补位,无符号数如unsigned int等,高位直接补0,有符号数如int,short ,long,char用符号位补齐,负数符号位为1,正数符号位为0,计算机使用补码:正数同原码,负数原码取反再加1。实际上右移n位,等于除以2^n,但是可能除不尽。
int result1 = 15;
printf("%d",result1 >> 2);
/*
15: 0000 0000 0000 0000 0000 0000 0000 1111
3: 0000 0000 0000 0000 0000 0000 0000 0011
*/
short result2 = -15;
printf("%d",result2 >> 3);
/*
-15: 1111 1111 1111 0001
-2: 1111 1111 1111 1110
*/
unsigned short result3 = 0xffe0;
printf("%d",result3 >> 4);
/*
0xffe0: 1111 1111 1110 0000
0x0ffe: 0000 1111 1111 1110
*/
char result4 = 15;
printf("%d",result4 >> 3);
/*
15: 0000 1111
1: 0000 0001
*/