版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wdays83892469/article/details/80287107
位运算比较数的大小(不出现比较运算符)
给定两个数a和b,不用比较运算符,返回较大的那一个
public class Code_01_GetMax {
public static int flip(int n) {
return n ^ 1;
}
public static int sign(int n) {
//(n >> 31) & 1 负数返回1,正数返回0,然后将结果取异或就是负数返回0,正数返回1
return flip((n >> 31) & 1);//负数返回0,正数返回1
}
//互斥条件变为位运算信息
public static int getMax1(int a, int b) {//将互斥条件变为位运算信息(有溢出问题)
int c = a - b;
int scA = sign(c);//负0正1
int scB = flip(scA);//负1正0
return a * scA + b * scB;//等价于 if(a-b>0) 返回a*1+b*0 if a-b<0 返回 a*0+b*1
}
//互斥条件变为位运算信息
public static 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;//a与b符号不同
int sameSab = flip(difSab);//a与b符号相同
//a b符号相同,做减法运算就不会溢出,转化为getMax1的情况
//a b符号不同 (a为正返回a) + ab符号相同(不会溢出) 差值c为正也返回a 也就是两个条件,只要有一个成立就返回a
//也就是下面这部分注释掉的伪代码所表示的含义
// if (a与b不同号&&a>0||a-b>0) {
// return a;
// }else{
// return b;
// }
//伪代码的互斥表示
int returnA = difSab * sa + sameSab * sc;
int returnB = flip(returnA);//不返回a就返回b
return a * returnA + b * returnB;
}
public static void main(String[] args) {
int a = -16;
int b = 1;
System.out.println(getMax1(a, b));
System.out.println(getMax2(a, b));
a = 2147483647;
b = -2147480000;
System.out.println(getMax1(a, b)); // wrong answer because of overflow
System.out.println(getMax2(a, b));
}
}