位操作运算符
###基本运算符*
运算符 | ~ | & | | | ^ | << | >> |
---|---|---|---|---|---|---|
含义 | 按位反 | 按位与 | 按位或 | 按位异或 | 左移 | 右移 |
1、按位反: ~
一元运算符,逐位取反,产生二进制反码;
例:
~(10010001) == 01101110;
2、按位与: &
二元运算符,逐位比较,都真才真(1 & 1 = 1);
例:
(10010001) & (00110000) == 00010000;
3、按位或: |
二元运算符,逐位比较,有真即真(1 | 0 = 1 或 1 | 1 = 1);
例:
(11101011) | (00100100) == 11101111;
4、按位异或: ^
二元运算符,逐位比较,一真一假为真(1 ^ 0 = 1);
例:
(11010011) ^ (10101010) == 01111001;
5、左移and右移: << and >>
左移运算符,将其左侧运算对象的每一位向左移动右侧运算对象指定的位数。左侧移除值丢失,右侧空出位置用0填充。
例:
(00001010) << 2 == (00101000); //相当于向高位移动
右移运算符,将其左侧运算对象的每一位向右移动右侧运算对象指定的位数。右侧移除值丢失,左侧空出位置,对于无符号类型用0填充,有符号类型不确定取决于机器,填充值不确定。
例:
//若为无符号类型
(10001010) >> 2 == (00100010); //相当于向低位移动
总的来说,左移产生新值每一个位向低位移动,右移产生新值将每一个位向高位移动,但是都是对副本操作,也就是说不改变原有值。若要改变可与赋值运算符结合形成<<=和>>=。
num >> n; //相当于num * pow(2,n)
num << n; //相当于num / pow(2,n)
以上中二元运算符&、|、^、>>、<<都可以与幅值运算符组合
如:
val |= (0o377)
即 val = val | (0o377)
###用法
假设有两个变量:
MASK 0 0 0 0 0 0 1 0
FLAG 1 0 0 1 0 1 1 0
1、掩码(mask),所谓掩码是指一些设置为1(透明)、0(不透明)的位组合。
表达式 FLAG & MASK
相当于用掩码覆盖在flags的位组合上,使MASK中为1的透明可见,为0的不可见;且若flags宽度 > MASK宽度,MASK宽度决定运算结果的宽度。
例:
(FLAG & MASK) == 00000010;
2、打开位(设置值),打开一个值中特定位,其他位保持不变。
表达式 FLAGS |= MASK
相当于把FLAGS中的1号位设置为1(打开),其他位保持不变。
例:
(FLAGS | MASK) == 10010110;
3、关闭位(清空位),类似于打开位,关闭特定位,其他位保持不变。
表达式 FLAGS & ~(MASK)
相当于把FLAGS中的1号位设置为0(关闭),其他位保持不变。
例:
(FLAGS & (~MASK)) == 10010100;
4、切换位,指打开关闭位,关闭打开位。
异或运算四种情况:
掩码MASK中为1,成功切换位;
1 ^ 1 = 0
1 ^ 0 = 1
掩码MASK中为0,保持不变;
0 ^ 0 = 0
0 ^ 1 = 1
例:
mask = 10110110;
flags = 00001111;
mask ^ flags = 10111001
flags中与mask中为1的位相对应的位都被切换了,mask为0相对应的flags的位保持不变;
5、检查位的值,检查某位是否被设置为1?不能直接比较flags与mask,即使某位为1,其他位会导致比较结果为假。因此,必须覆盖flags中其他位,只比较1号位;
例:
if((flags & mask) == mask) puts("Wow!");
掩码宽度至少要与其覆盖值相同,避免信息漏过边界
6、移位运算符,针对2的幂提供了快速有效的乘法和除法,类似于十进制中移动小数点来乘以或除以10。
number << n //number乘以2的n次幂
number >> n //如果number为非负,则用number除以2的n次幂
还可用于从较大单元中提取一些位。
例如,假设用一个unsign char类型的值表示颜色,低阶字节存储红色强度,下一字节存储绿色强度,第三个字节存储蓝色强度。我们可以依次提取出来存储到3个不同的unsiged char类型中。
#define BYTE_MASK 0xff
unsigned long color = 0x002a162f;
unsigned char blue, green, red;
red = color & BYTE_MASK;
green = (color >> 8) & BYTE_MASK;
red = (color >> 16) & BYTE_MASK;
2019.12.1
修炼之路(一)
未完待续
归期不定
by lx