位运算的题目

【题目】

给定两个有符号32位整数a和b,返回a和b中较大的。 

【要求】

不用做任何比较判断。

// 0 -> 1  1 -> 0
int flip(int n){
    return n ^ 1;
}

// n非负,返回1  n为负,返回0
int sign(int n){
    return flip((n >> 31) & 1);
}

// 缺点:c会溢出
int getMax1(int a, int b){
    int c = a - b;
    int scA = sign(c);
    int scB = flip(scA);
    // scA 和 scB只能有一个为1,互斥
    return a * scA + b * scB;
}

// 解决了c溢出的问题
int getMax2(int a, int b){
    int c = a - b;
    int sa = sign(a);
    int sb = sign(b);
    int sc = sign(c);
    int difSab = sa ^ sb;
    int sameSab = flip(difSab);
    int returnA = difSab * sa + sameSab * sc;
    int returnB = flip(returnA);
    return a * returnA + b * returnB;
}

【判断一个32位正数是不是2的幂、4的幂】

2的幂:32位只有一个1。如何判断:

1)求最右侧1,看是否与原数相等

2)取32位上的一个1,将其减1,跟原数做与,结果为0

4的幂:32位只有一个1,且1在第0,2,4...位上。如何判断:

先判断是2的幂,再跟0101010101...010101(32位)相与,结果不为0

bool is2Power(int n){
    return (n & (n - 1)) == 0;
}

bool is4Power(int n){
    return (n & (n - 1)) == 0 && (n & 0x55555555) != 0;
}

【题目】

给定两个有符号32位整数a和b,不能使用算术运算符,分别实现a和b的加、减、乘、除运算

【要求】

如果给定a、b执行加减乘除的运算结果会导致数据的溢出,那么你实现的函数不必对此负责,除此之外请保证计算过程不发生溢出。

int add(int a, int b){
    int sum = a;
    while(b != 0){
        sum = a ^ b;
        b = (a & b) << 1;
        a = sum;
    }
    return sum;
}

int negNum(int n){
    return add(~ n, 1);
}

int minuss(int a, int b){
    return add(a, negNum(b));
}

bool isNeg(int n){
    return n < 0;
}

int multi(int a, int b){
    int x = isNeg(a) ? negNum(a) : a;
    int y = isNeg(b) ? negNum(b) : b;
    int res = 0;
    while(y != 0){
        if((y & 1) != 0){
            res = add(res, x);
        }
        x <<= 1;
        y >>= 1;
    }
    return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
}

int divv(int a, int b){
    int x = isNeg(a) ? negNum(a) : a;
    int y = isNeg(b) ? negNum(b) : b;
    int res = 0;
    for(int i = 31; i >= 0; i = minuss(i, 1)){
        if((x >> i) >= y){
            res |= (1 << i);
            x = minuss(x, y << i);
        }
    }
    return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

芜湖高学成

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

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

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

打赏作者

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

抵扣说明:

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

余额充值