位运算

232 阅读1分钟

位运算

位运算的分类

位运算的应用

位运算的分类

按位运算:左移、右移、按位与按位或、异或、 取反,取相反数

  • 右移:>>右移一位相当于 /2 常见用法 mid=(l-r)>>1+l;用这种方法可以避免mid=(l+R)/2l+R会超过int的范围的问题,并且位运算的速度比mid=(l-r)>>1+l;的速度快很多

  • 左移 :<<左移一位相当于 *2 没什么好说的就是速度比较快

  • 按位与:&都为一为一其他为0、0&0=00&1=11&1=1

01010110
        &
01001001

按位与的结果

01000000
  • 按位或:|1|1=11|0=10|0=0

  • 异或:^,可以理解为无进位加法 1^1=00^1=10^0=0

  • 取反:~取反包含符号位0全部变为1,1全部变为0.

  • 取相反数:-,这是一个复杂的过程 有符号正数在内存中的存储为 原码第一位符号位为0 而负数在内存中的存储为补码 先把正数的符号位变为1然后去反加一就可以了

010011 //原码
101100//取反 第一位变为1表示负数
101101//加一变为对应的负数

位运算的应用

-n=~n+1;

  • 如何得到一个数的最低位的1:
x=n;
t=x&(~n+1)
  • 如何得到一个数的最高位:可以利用循环不断左移、知道为0记录个数n然后pow(2,n);或者下面这种方法,这一种学习的时候看了一个人按位运算的求法的播客但是找不到了,就没发了
int cnt=0;
int x;//带去最高位的数
while(x!=0)
{
    x>>1;
}
int d=pow(2,n);
  • 交换两个数字可以利用异或的性质可以更加快速的交换: a^a=0 0^b=b
arr[l]=arr[l]^arr[r];
arr[r]=arr[l]^arr[r];//arr[r]=arr[l];
arr[l]=arr[l]^arr[r];

这里第二句相当于 arr[r]=arr[l]^arr[r]^arr[r]后面两个异或为0所以可以等效arr[r]=arr[l]位运算不分顺序怎么来都是一样的。