位运算

位运算:

对整数在内存中的二进制位进行操作。一般操作如下:

操作数的存放方式也分为大端模式,小端模式;大端模式:从高字节到低字节。小端模式:从低字节到高字节。
例如0x1234的存放方式:
小端:
内存地址存放内容
0x40000x34
0x40010x12
大端:
内存地址存放内容
0x40000x12
0x40010x34

判断存放方式是大端还是小端模式:
void checkCpu(){
    unsigned short data = 0x1122;
    unsigned char *p = (unsigned char *)&data;
    if(*p==0x22)
        小端
    else
        大端
}

介绍2个位运算的等式:
-n = ~(n-1)=-n+1;
获取二进制位的最后一个1:n&(-n);
去掉二进制位的最后一个1:n&(n-1);

位运算实现平均数(防止大数相加之后的溢出情况):
int anverage(int x,int y){
    return (x&y)+((x^y)>>1);
}

位运算实现绝对值:
int abs(int x){
    //负数右移31位 变成0xffffffff 正数则为:0x00000000
    int y;
    y = x>>31;
    return (x^y)-y;
}

位运算实现加法:
int add(int num1,int num2){
    /**
    二进制加法:0+0=0;0+1=1;1+0=1;1+1=0进位是1;
    所以类似于异或操作,只有进位的时候选择的x&y 1&1=1,0&0=0不存在进位
    */
    int tmp,carry;
    if(num2 == 0)
        return num1;
    tmp = num1^num2;
    carry = (num1&num2)<<1;
    return add(tmp,carry);
}

位运算实现乘法:
int multi(int a,int b){
    /**
    分析 乘法同时也是加法的一种变形
    1011*1010 = 1011*1000+1011*0010;
    好比1011<<3 + 1011<<1;
    通过上面的tips:获取1:n&(-n) 去掉1:n&(n-1)
    通过map<int,int>存储数值 和位数
    */
    bool flag = (b<0);
    if(b<0) b = -b;
    if(a==0 || b==0)
        return 0;
    map<int,int> bit_map;
    int i;
    int sum=0;
    for(i=0;i<32;i++)
        bit_map.insert(1<<i,i);
    while(b>0){
        int last_one = bit_map[b&(-b)];
        sum += a<<(last_one);
        b &= (b-1);
    }
    if(flag)
        return -sum;
    else
        return sum;
}

位运算实现除法:
int div(const int x,const int y){
    int left_num = x;
    int ans = 0;
    while(left_num>=y){
        int mul = 1;
        while(y*mul <=(left_num)>>1)
            mul <<= 1;
        ans += mul;
        left_num -= y*mul;
    }
    return ans;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值