位运算相关(应用待补充)

按位取反~

即0变为1,1变为0

按位与&

0&0=0,0&1=0,1&0=0,1&1=1

  • 用于计算n的二进制表示中最低位1出现的位置
  int lowbit(int n){
  	return n&(-n);
  }
  //0000 0001 & 0111 1111
//查看某一个数是不是2的平方数
n&(n-1)==0 //等于0表示n为2的平方数

a & b <= min(a,b)
按位与最大的最长子数组

关于负数的二进制问题:

负数的二进制用补码表示:原码取反为反码,反码加一变成补码。

1:0000 0001

-11000 0001

反码:0111 1110

补码:0111 1111

正数的原码、反码、补码相同

实现原理:

负数表示是通过取反再加1的形式,原本为1的取反后都变为0,与加1进行&运算,则得到最低为1出现的位置。

  • 计算n的二进制表示中有几个1
int numOfOne(int n){
	int count=0;
	while(n){
		count++;
		n=n&(n-1);
	}
	return count;
}

实现原理

每一次执行n&(n-1)都会消掉一个“合理的1”

  • 用来截取n的最低几位

按位异或^

0^0=1,0^1=0,1^0=0,1^1=1

相同为1,不同为0

  • 统计出现个数为奇数个的数字

按位或 |

0|1=1,1|0=1,1|1=1,0|0=0

只要有0出现时结果就是1,否则为0

  • 将二进制中的某几位位置为1

    n=n|1将最后一位变成1

在这里插入图片描述

左移运算符<<(在补码上面操作)

左移就是将二进制的每一个数都往左移动一位,高位舍去,低位补0

  • 左移一位相当于是*2,左移n位,相当于是2的n次方
  • 有符号数不完全适用,因为左移有可能导致符号变化
**1<<1**
原码:000000001
第一步:反码:00000001
第二步:补码:00000001
第三步:移动:00000010
第四步:反码:00000010
第五步:原码:00000010
也就是1*(2^1)=2

**-3<<2**-3左移两位
原码:10000011
第一步:反码:11111100
第二步:补码:11111101
第三步:移动:11110100(得到的是补码)
第四步:反码:11110011
第五步:原码:10001100
(因为负数的补码是最后+1,所以再往原码转化的时候应该-1)
也就是-3*(2^2)=-12

右移运算符>>(在补码上面操作)

右移就是将二进制的每一个数都往右移动一位,高位的空位补符号位,即正数补零,负数补1,低位舍去

  • 右移一位相当于/2
15>>2
原码:00001111
第一步:反码:00001111
第二步:补码:00001111
第三步:移动:00000011
第四步:反码:00000011
第五步:原码:00000011
也就是15/(2^2)=3
-4>>2
原码:10000100
第一步:反码:11111011
第二步:补码:11111100
第三步:移动:11111111
第四步:反码:11111110
第五步:原码:10000001
(因为负数的补码是最后+1,所以再往原码转化的时候应该-1)
也就是-4/(2^2)=-1

应用

  • 判断奇偶性x&1值为1是奇数,因为奇数的最后一位一定是1
  • 获取二进制位是1还是0
    • 把1左移到第i位,与x做与运算,就可以得出第i位是1还是0
  • 交换两个整型变量的值
  • 求整数的绝对值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值