数学问题——位运算比较数的大小

版权声明:本文为博主原创文章,未经博主允许不得转载。 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));


    }

}

猜你喜欢

转载自blog.csdn.net/wdays83892469/article/details/80287107