按位逻辑运算
取反 ~
一元运算符~把1变为0,把0变为1
1 | ~(10011010) |
按位与 &
二元运算符&通过逐位比较两个运算对象,生成一个新值。对于每个位,只有两个运算对象中相应的位都为1时,结果才为1
1 | (10010011) & (00111101) |
按位或 |
二元运算符&通过逐位比较两个运算对象,生成一个新值。对于每个位,只有两个运算对象中相应的位都为1时,结果才为1
1 | (10010011) | (00111101) |
按位异或 ^
二元运算符&通过逐位比较两个运算对象,生成一个新值。对于每个位,只有两个运算对象中相应的位都为1时,结果才为1
1 | (10010011) ^ (00111101) |
掩码
mask = 2 (0000 0010)
1 | flag = flag & mask |
那么flag 的位都会置位为0 除了掩码为1的第二位
可以这样类比:把掩码中的0看作不透明,1看作透明 用掩码中的0将flag给掩盖起来了
打开位
1 | flag = flag | mask |
flags的1号位设置为1,且其他位不变
根据MASK中为1的位,把flags中对应的位设置为1,其他位不变
关闭位
1 | flag = flag & ~mask; |
根据MASK中为1的位,把flags中对应的位设置为0,其他位不变
切换位
1 | flag = flag ^ mask |
根据MASK中为1的位,把flags中对应的位取反,其他位不变
检查位的值
flags中1号位是否被设置为1
1 | if ((flags & MASK) == MASK) |
移位运算符
左移 <<
左移运算符(<<)将其左侧运算对象每一位的值向左移动其右侧运算对象指定的位数。左侧运算对象移出左末端位的值丢失,用0填充空出的位置。
1 | (10001010) << 2 |
该操作产生了一个新的位值,但是不改变其运算对象。例如,假设stonk为1,那么stonk<<2为4,但是stonk本身不变,仍为1。可以使用左移赋值运算符(<<=)来更改变量的值。该运算符将变量中的位向左移动其右侧运算对象给定值的位数。如下例:
1 | int stonk = 1; |
右移 >>
右移运算符(>>)将其左侧运算对象每一位的值向右移动其右侧运算对象指定的位数。左侧运算对象移出右末端位的值丢。
无符号 用0补位
1
2(10001010) >> 2
(00100010)有符号 结果取决于机器 用0或者符号位的副本填充
1
2
3
4(10001010) >> 2 // 表达式,有符号值
(00100010) // 在某些系统中的结果值
(10001010) >> 2 // 表达式,有符号值
(11100010) // 在另一些系统上的结果值
运用
移位运算符针对2的幂提供快速有效的乘法和除法
1
2number << n // number 乘以2的n次幂
number >> n移位运算符针对2的幂提供快速有效的乘法和除法
假设用一个unsigned long类型的值表示颜色值,低阶位字节存储红色的强度,下一个字节存储绿色的强度,第3个字节存储蓝色的强度。随后你希望把每种颜色的强度分别存储在3个不同的unsigned char类型的变量中1
2
3
4
5
6
unsigned long color = 0x002a162f;
unsigned char blue, green, red;
red = color & BYTE_MASK;
green = (color >> 8) & BYTE_MASK;
blue = (color >> 16) & BYTE_MASK;