科锐课堂笔记:2017/3/27 位运算和位段

  按位异或:相同为0,不同为1。
  A xor A = 0;
  A xor 1 = not A;
  A xor 0 = A;

  由1、3组合可知,任何数异或同一个数2次等于其本身,利用这点可对两个数进行交换,如:

int nNum1=1,nNum2=2;
nNum1 = nNum1 ^ nNum2;
nNum2 = nNum1 ^ nNum2; // = nNum1^nNum2^nNum2,就=nNum1
nNum1 = nNum1 ^ nNum2; // 此时nNum2的已等于nNum1,
                       // 所以 = nNum1^nNum2^nNum1,结果等于nNum2
  两个数互相交换通过如此或异就完成了,不过在如今的年代,为了节省一个中间变量那么几字节的内存而使代码可读性变差,得不偿失,况且异或用在变量交换这种小事上也是大材小用了,扩展点想,利用异或的特性,备份一段数据只需其一半的容量空间就够了,前后一半相异或保存,只要有一半数据就能得到另一半数据。
  异或主要的几个用途:
   1、 清0。
  2、 交换两数。
  3、 备份数据(只占一半空间)。
  4、 局部取反。


  C语言中的位移都是算术位移,算术左移同逻辑左移一样都是高位丢弃,低位补0。区别在右移上,算术右移无符号数同逻辑右移一样低位丢弃,高位补0;但如果算术右移一个有符号数,那么它将低位丢弃,高位补符号位(也就是右移负数时,算术右移与逻辑右移的结果会不同)。
  算术左移等同于乘以2的幂,算术右移正数时等于除以2的幂,当右移一个负数时,想得到正确结果先要加上2的幂-1再右移,否则当右移不能整除时,不会得到正确的结果。


  用位运算求绝对值(无判断分支)

int NewAbs(int n) {
	int nSign = n >> 31; // nSign=0(n为正数)或0xFFFFFFFF(n为负数)
	int nRet = n ^ nSign; // 对于正数nRet=n,对于负数nRet=~n
	return nRet-nSign; // 对于正数返回n本身,对于负数求补(取反加1)后返回,也就是它的正数值。
}


  位段:
  用关键字struct包裹,定义位段 类型 位段名:数字(表占几位)。位段的占位是从低位算起,如果定义时没有位段名表只占位数(不引用),如果既没有位段名且占位数字为0则表示放弃本字节单位,下一个位段将在新的对齐字节单位开始。
  对一个位段成员赋值大于成员的位数,取此赋值数的低位段数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值