位运算(c语言)

位运算

位运算的分类

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

  • 右移:>>右移一位相当于 /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

如何得到一个数的最低位的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];

这里面交换的两个值一定不能相等,不然会得到全0

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

三、打印一个数所有的二进制位

void ShowBit(int i)
{
    // 这里要用无符号数不然下面循环判断条件会出错,因为1左移31位位
    // 1000 0000 0000 0000 0000 0000 0000 0000 为负数
    // 况且左移的时候如果为负数int类型的话会在最高位补符号位也会影响结果
    unsigned int x = 1 << 31;
    while (x > 0)
    {
        //&运算的优先级小于==的要加括号
        if ((x & i) == 0)
        {
            printf("0");
        }
        else
        {
            printf("1");
        }
        x = x >> 1;
    }
    printf("\n");
}

四、把一个数对应Bit位位置置为1

//对应位变为1 1的第一位已经为1所以要把1左移i-1位
#define ReWriteBitO(x,i) (x=x|(1<<(i-1)) )
0000 0000 0000 0000 0000 0000 0000 0001 
//左移i-1位 对应位置变为1 
// 1和任何数或运算都为1
// 0和任何数运算都等于他自身 从而达到对于位置置1的目的

五、把一个数对应位置置0

#define RewriteBitZ(x,i) (x=x&(~(1<<i-1)) )
// 我们都知道0和任何数位&运算都为0
// 1和任何数位运算& 结果都为它本身
// 我们要把对应数位变为0我们就要得到对应数位为0其他数位为1的数
// 我们无法立刻得到这样的数
// 可以通过找对应数位为1其他为0然后取反的方法来完成
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学c的小李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值