一些异或运算以及掩码的奇技淫巧
2015-10-31 21:58
423 查看
异或运算的一些特性
1、一个数和自己做异或的结果是0。如果需要一个常数0,x86平台的编译器可能会生成这样的指令:xorl %eax, %eax。不管
eax寄存器里的值原来是多少,做异或运算都能得到0,这条指令比同样效果的
movl $0, %eax指令快。
2、从异或的真值表可以看出,不管是0还是1,和0做异或值不变,和1做异或得到原值的相反值。可以利用这个特性配合掩码实现某些位的翻转,例如:
unsigned int a, b, mask = 1 << 6; a = 0x12345678; b = a ^ mask; /* flip the 6th bit */
3、如果a1 ^ a2 ^ a3 ^ ... ^ an的结果是1,则表示a1、a2、a3...an之中1的个数为奇数个,否则为偶数个。这条性质可用于奇偶校验(Parity Check),比如在串口通信过程中,每个字节的数据都计算一个校验位,数据和校验位一起发送出去,这样接收方可以根据校验位粗略地判断接收到的数据是否有误。
4、x ^ x ^ y == y,因为x ^ x == 0,0 ^ y == y。这个性质有什么用呢?我们来看这样一个问题:交换两个变量的值,不得借助于额外的存储空间,所以就不能采用
temp = a; a = b; b = temp;的办法了。利用位运算可以这样做交换:
a = a ^ b; b = b ^ a; a = a ^ b;
分析一下这个过程。为了避免混淆,把a和b的初值分别记为a0和b0。第一行,
a = a0 ^ b0;第二行,把a的新值代入,得到
b = b0 ^ a0 ^ b0,等号右边的b0相当于上面公式中的x,a0相当于y,所以结果为a0;第三行,把a和b的新值代入,得到
a = a0 ^ b0 ^ a0,结果为b0。
掩码
如果要对一个整数中的某些位进行操作,怎样表示这些位在整数中的位置呢?可以用掩码(Mask)来表示,比如掩码0x0000ff00表示对一个32位整数的8~15位进行操作,举例如下。1、取出8~15位。
unsigned int a, b, mask = 0x0000ff00; a = 0x12345678; b = (a & mask) >> 8; /* 0x00000056 */
这样也可以达到同样的效果:
b = (a >> 8) & ~(~0 << 8);
2、将8~15位清0。
unsigned int a, b, mask = 0x0000ff00; a = 0x12345678; b = a & ~mask; /* 0x12340078 */
3、将8~15位置1。
unsigned int a, b, mask = 0x0000ff00; a = 0x12345678; b = a | mask; /* 0x1234ff78 */
相关文章推荐
- 【The Expendables】团队博客目录
- ubuntu安装Python环境以及科学计算环境
- springmvc原始入门(帮助理解springmvc流程)
- 主存储器的地址编码问题
- 【系统性能优化】(二)数据库设计
- 乘坐公交
- mybatis使用注解2
- 【Little_things】简单的Client/Server通信小程序(java socket)
- linux驱动platform平台设备总线
- SQL语句的分类
- lvs三种模型
- 研三上学习计划
- 求解最大子数组问题的三种方法
- MAC 下安装MATLAB2014b
- [LeetCode] Bulls and Cows
- Markdown 语法说明 (简体中文版)
- mybatis注解详解
- 通过weblogic自带脚本正常关闭受管理服务器方法
- 分享一个在线下载视频的网站
- spring 入门01--IoC与DI