其实位运算最有用的是在程序中发挥什么作用,往往是妙用,会让你的程序变得简洁高效许多。用其他办法无法实现位运算的效率。今天我不讲运算规则,而从作用入手,用我们习惯的数学语言描述它们的作用,C/C++的位运算包括:
1. 按位与&:a&b,作用有。
- 在硬件或系统相关代码中出现时往往用来清除某些位,保留另一些位。如:a&0xffff0000,即表示保留a的高位字(word),清除低位字(word)。
- 在应用软件里,一个重要作用是将运算结果限制在两个操作数中较小的一个和0之间。语义可以表示为 0<= a&b<=min(a,b),但不一定可以取到之间所有的整数,若min(a,b)是偶数,那么a&b只能是0或min(a,b),而且出现的概率均等。若min(a,b)是奇数,情况比较复杂,但仍然遵循上面的语义。
- 在图像处理应用中,可以用黑白图像同原始彩色图像进行&运算,从原图中截取黑白图像的白色区域所限范围的内容。黑色区域所限内容,在生成的结果图像中全部变为黑色。
- 用于求模(除求余数),a&b,(即a除以b+1求余数),b为二进制全1的数。即2^n-1
2. 按位或|:a|b ,
- 若a, b都是信息位组成的数,则a|b对位信息进行合并,结果包含了a,b原有所有信息位。如0xf0f0|0x0f0f=0xffff。
- a|1 每个数重复一次的奇数序列。也就是说a|1都是奇数。
- 在图像处理应用中,同&运算恰恰相反,通过|运算,从原图中截取黑白图像的黑色区域所限范围的内容。白色区域所限内容,在生成的结果图像中全部变为白色。
3. 按位异或^: a^b,
- 实现无进位的加法操作。实际意义在于,清除相同的位,不同的位置1。也就是找到不同的位。结果是不同的位的掩码。a^a=0;经常用于高效的清0一个变量。
- 加密算法中,用于简单加解密,有如下性质:a^b^a=b,a^b^b=a,且满足交换律。怎么进行简单加密,知道了吧:-).
- 数列重排,n是自然数列,a取任何固定整数,n^a就可以生成一个不会重复的自然数列。只不过,数被部分颠倒重排。
- 在图像处理应用中,彩色^白=反色图像,彩色^黑=彩色图像。如果同黑白图像进行^,则生成黑色区域原色,白色区域反色的图像。
4. 按位取反~: ~a
- ~a 用于求补码运算,从而将减法转换为加法。需要注意,变减为加必须指定运算所使用的位长。 a补码=~a+1,b-a=丢掉进位(b+a补码)
- 同异或有等价表达式:~a=a^全1
5. 右移>>: a>>b
- a>>b相当于a/2^b (此处^表示幂运算),b可以为所有有符号整数。丢掉正反向进位。
6. 左移<<: a<<b
- a<<b相当于a*2^b (此处^表示幂运算),b可以为所有有符号整数。丢掉正反向进位。