题目描述
给你两个有符号整数a和b,请你返回ab中较大的值,要求,不能使用比较判断,也就是不能使用if。
思路分析
首先,如何用位运算取出一个数的符号位?
int值右移31位后,最后一位就是符号位。然后再利用异或运算把0变1,1变0
//右移31位,取出符号位,然后0变1,1变0
//结果就是,非负数为1,负数为0
public static int sign(int n){
return flip( (n>>31)&1 );
}
//^和1按位异或,相同为0,不同为1
//就把0变1,1变0
public static int flip(int n){
return n^1;
}
然后,如何不使用if、else来实现判断呢?
用互斥条件相加来实现。
所谓互斥条件就是0和1,然后,互斥条件永远都只有一个能成立,因为0乘以任何数都是0,当互斥条件在同一个式子中出现,并相加,那么,加号两边永远都有一边为0,这就是用互斥条件相加来实现if判断。
例如:
return a * returnA + b * returnB;
returnA 和returnB 互斥,必须一个0一个1。那么,下面式子加号两边永远都只能实现一个,因此,就实现了if、else的结构。
代码
此题要考虑a-b溢出的情况,因此,要判断一下ab同号问题。
//用互斥条件实现不基于比较求出较大值
public static int getMax(int a,int b){
int c = a-b;//ab差值
int sa = sign(a);//a的符号
int sb = sign(b);//b的符号
int sc = sign(c);//c的符号
int difAb = sa ^ sb;//ab的符号是否不同,不同为1,相同为0
int sameAb = flip(difAb);//ab的符号是否相同,相同为1,不同为0
//ab符号不同时,a为正数,说明a大,返回a
//ab符号相同时,a-b大于0,说明a大,返回a
int returnA= difAb * sa + sameAb * sc;
int returnB=flip(returnA);//返回b的情况与返回a互斥
return a * returnA + b * returnB;//利用互斥实现if判断
}