位运算chapter1:无if,else,switch,?:实现求两数较大/小者

文章介绍了如何通过C++代码实现安全地计算两个整数的最大值,避免了`maxfast`函数因溢出可能导致的错误。`getMax`函数考虑了符号差异,确保了对无符号类型的兼容性,以解决LeetCode面试题中的最大数值问题。
摘要由CSDN通过智能技术生成
class Solution {
private:
    // 非负返回0,负数返回-1
    int8_t sign(int n) {
        return n >> 31;
    }
public:
    // c溢出会导致错误
    int maxfast(int a, int b) {
        int c = a - b;
        int8_t sc = sign(c);// c的符号
        return a & ~sc | b & sc;
    }
    // 无任何风险
    int getMax(int a, int b) {
        int c = a - b;

        int8_t sa = sign(a);// a的符号
        int8_t sb = sign(b);// b的符号
        int8_t sc = sign(c);// c的符号

        int8_t diffAB = sa ^ sb;// AB符号不同为-1,相同为0
        int8_t sameAB = ~diffAB;// AB符号相同为-1,不同为0

        int8_t returnB = diffAB & sa | sameAB & sc;
        int8_t returnA = ~returnB;

        return a & returnA | b & returnB;// 把a,b的位置互换就是求最小。
    }
};

任何数&-1都是该数本身,即a&-1=a,任何数&0都为0,即a&0=0
另外,-1^0=-1

这里只详细解释这句话的用途:int8_t returnB = diffAB & sa | sameAB & sc;

要return b,就说明b是那个更大的数,那么,一共有两种情况b是较大的数:

①:AB异号,且A是负数
当AB异号时,如果A是负数,那么B一定是非负数,B一定是较大的那个数

②:AB同号,且C是负数
当AB同号时,如果C是负数,那么A-B<0,即A<B,B一定是较大的那个数

这两种情况里的小前提是的关系,而这两种情况分别是的关系,对应位运算中的'&'和'|'

因此,有了这句话 int8_t returnB = diffAB & sa | sameAB & sc;

可以证明没有其他情况------------------------------------------------------------------------------------

如果a和b符号一样,优先使用maxfast。

但是不足的地方是这个算法无法处理unsigned类型的情况,也就是无符号类型的情况。

另外,在maxfast里,c溢出导致的结果错误逻辑如下:
令A=-2147483648,B=2147483647

   10000000 00000000 00000000 00000000 (-2147483648 的补码表示)
-  01111111 11111111 11111111 11111111 (2147483647 的补码表示)
----------------------------------------
   00000000 00000000 00000000 00000001 (运算结果)

 C此时等于1大于0
那么由于溢出,程序就会误以为A>B,最后就会导致结果错误。

题目测试点:

面试题 16.07. 最大数值 - 力扣(LeetCode)

获取最大值_牛客题霸_牛客网 (nowcoder.com)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值