取模运算% 按位与& 以及 位运算

在研究某大佬的代码时,突然发现了这样一条用来判断奇偶数的语句:

if(x&1) {...}

带着想探究事物本质的好奇心 (代码说它想变得高大上!),去搜了搜取模运算%按位与&的关系,于是打开了新世界的大门 (「・ω・)「

  • 注:位运算与&的效率要比取模运算%10倍以上

位运算符简介

&、或|、异或^、右移>>、左移<<,取反~

按位与 &

  • 0&0=0; 0&1=0; 1&0=0; 1&1=1; 简记为“同1则1
  • 应用:
    • 清零:x&0
    • 取二进制数的某一位:例如取x=10010110的右数第三位,则x&00000100 = 00000100,说明x的右数第三位是1
    • 判断奇偶数代替取模运算x%2==1: 奇数x&1=1,偶数x&1=0,效率更高

按位或 |

  • 0|0=0; 0|1=1; 1|0=1; 1|1=1; 简记为“有1则1
  • 应用:
    • 使二进制数的某些位为1:例如使x=10001000的右数第1,2位取1,则x|00000011 = 10001011

按位异或 ^

  • 0^0=0; 0^1=1; 1^0=1; 1^1=0; 简记为“同0异1
  • 自反性: x^y^y = xx^0 = 0x^x = 0
  • 应用:
    • 不利用中间变量实现变量值互换
    //x = 3 = 0011  y = 5 = 0101
    x = x^y; // x1 = (x^y=0110)
    y = x^y; // y = (x1^y=0110^0101=0011=3)
    x = x^y; // x = (x1^y1=0110^0011=0101=5) 交换完成
    
    • 特殊的数组筛选重复值:1~100放在长度为101的数组中,只有唯一的一个值重复,其它均只出现一次 -> 将数组中的元素全部异或,再减去1-100的全部异或,即可得到重复的数值

按位右移 >>

  • 将某数的二进制位全部右移指定位,相当于除以2n,正数左补0,负数左补1,右边移出去的位丢弃,例如00100110>>2 = 00001001 即 38>>2 = 38/4 = 9(余数舍弃)

按位左移 <<

  • 将某数的二进制位全部左移指定位(当移出的位中不含1时,相当于乘以2n)右补0,左边移出去的位丢弃,例如00001101<<2 = 00110100 即 13<<2 = 13*4 =52

按位取反 ~

  • 将某数的二进制位数全部取反,0变1,1变0,例如~52 = ~00110100 = 11001011 = 203 = 255-52

综合应用示例

  1. 防溢出求平均数:(x+y)/2(x&y)+((x^y)>>1)
  2. 求绝对值:
    int abs(int x) { 
    	int y; 
    	y = x >> 31; 
    	return (x^y)-y;  //(x+y)^y 
    } 
    
  3. 替代部分条件语句:if (x==a) x = b; else x = a;x = (x==a ? b : a);x = a ^ b ^ x;
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值