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,最后就会导致结果错误。
题目测试点: