位运算和常见用途

位运算

位运算的操作对象只能为整型或字符型数据,位运算把运算对象看作是二进制,按位完成指定的运算

位运算直接对内存进行操作,灵活使用可以简化和优化很多程序

1.位运算符号

符号含义
&按位与
|按位或
^按位异或
<<左移
>>右移
~取反

按位与 &

指将参加运算的数字,按二进制位进行“与”运算

规则:

0 & 0=0 0 &1=0

1 & 0=0 1 & 1=1

即:两位同时为 1 ,结果才为 1 ,否则为 0

例: 3&50000 0011 & 0000 0101 = 0000 0001 因此, 3&5 的值得 1

按位或 |

指参加运算的两个数字,按二进制位进行“或”运算

规则:

0|0=0 0|1=1

1|0=1 1|1=1

即 :两位只要有一个为 1 ,其值为 1 ,否则为 0

例: 3|5  即 0000 0011 | 0000 0101 = 0000 0111 因此, 3|5 的值得 7

按位异或 ^

指参加运算的两个数字,按二进制位进行“异或”运算

规则:

0 ^ 0=0 0 ^ 1=1

1 ^ 0=1 1 ^ 1=0

即:两位值不同,则结果为 1 ,否则为 0

例: 3^50000 0011 ^ 0000 0101 = 0000 0110 因此, 3^5 的值得 6

左移 <<

左移运算是用来将一个数的各个二进制位左移 n 个单位, n 由右操作数指定,左移后其右边空出的位用 0 替补,高位左移溢出则直接舍弃

特别的,在高位没有 1 的情况下,左移 1 位相当于该数乘以 2 ,左移 2 位相当于该数乘以 415<<2=60 ,即 15 乘了 4 ,但此结论只适用于该数左移时被溢出舍弃的高位中不包含 1 的情况

例: 143<<2 结果为 60 因为 143 转换为进制为 10001111 ,左移 200111100 ,结果为 60

右移 >>

右移运算符是用来将一个数的各二进制位右移 n 个单位, n 由右操作数指定,移到右端的低位被舍弃,同时高位补 0

取反 ~

按位取反运算符是指将整数的各个二进制位都取反,即 1 变为 00 变为 1

例:~9=-10 ,因为 9(00001001) 所有位取反即为 (11110110) ,这个数最高位是 1 ,所以是补码,补码还原成反码(反码等于补码减 1 )得到 (11110101) ,再还原为原码(反码到原码最高位不变,其它各位取反)等于 (10001010) , 十进制为 -10

2.用法

(1). 判断奇偶数

int f(int num){
    if(num&1)
        return 0;//奇数
    else
        return 1;//偶数
}

(2). 判断2的幂次方

int f(int num){
    if(num&(num-1))
        return 0;
    else 
        return 1;
}

(3). 计算一个数的二进制中 1 的个数

//一
int f(int num){
    int ans=0,n=1;
    while(n){
        if(num&n)ans++;
        n<<=1;
    }
    return ans;
}

//二
int f(int num){
    int ans=0;
    while(num){
        num=num&(num-1);
        ans++;
    }
    return ans;
}

(4). 对于异或^

异或的性质:

  • 交换律:a^b =b^a
  • 结合律:( a^b ) ^ c = a ^( b^c )

特别的,任何数与 0 异或都保留原值 a ^ 0 = a

相同的数异或得到 **0 ** a ^ a = 0 a ^ b ^ b = a

交换两个数:

a = a^b; b = b^a; a = a^b;

实例:给出 n 个整数,n 为奇数,其中有且仅有一个数出现了奇数次,其余的数都出现了偶数次。用线性时间复杂度、常数空间复杂度找出出现了奇数次的那个数

#include<iostream>
using namespace std;
int main(){
    int n,ans=0,num;
    cin>>n;
    while(n--){
        cin>>num;
        ans^=num;
    }
    cout<<ans<<endl;
    return 0;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

花崽oyf

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

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

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

打赏作者

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

抵扣说明:

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

余额充值