异或

左移:高位丢弃、低位补0

右移:无符号数:高位补0,低位丢弃;有符号数:高位补该数的符号位,低位丢弃(正数,高位补0;负数,高位补1)

无符号右移:无论正数负数,高位补0,低位丢弃

 

1.统计一个数的二进制表示中有几个1?

    public int NumberOf1(int n) {
        //判断一个数的二进制表示中有几个1
        /*
         * 判断某位是不是1,改位和1做位与运算,结果为1,表明该位是1
         * 
         */
        int count = 0;
        int flag = 1;
        while(flag != 0){
            if((n&flag) != 0){
                count++;
            }
            flag = (flag << 1);
        }
        return count; 
        
    }
    public int NumberOf1(int n) {
        //判断一个数的二进制表示中有几个1
        
        //任何一个数与该数减一做与运算,相当于把该数二进制表示的最后一个1变成0
        int count = 0;
        while(n!=0){
            count++;
            n = (n-1)&n;
        }
        return count;
    }

 

2.判断一个数是否为2的整数次方?

如果一个数是2的整数次方,那么该数的二进制表示中,只有一位是1.

如果你n&(n-1) == 0 ,表明该数是2的整数次方

n&(n-1)将n的二进制表示中的最后一个1变成0

    //判断一个数是否为2的整数次方
    public boolean is2mi(int n){
        if(n<0){
            n=-n;
        }
        if(n==0){
            return false;
        }else if((n&(n-1)) == 0){
            return true;
        }else{
            return false;
        }
    }

 

3.两个整数m和n,统计改变m的二进制表示中的几位数可以将m变成n?

其实就是统计m和n的二进制表示中有几位不相同

异或:相同为0,不同为1

先异或,异或的结果中1的个数就是所求

    //判断m和n的二进制表示中有几位不同
    public int diffMandN(int m,int n){
        int y = m^n; //m和n异或的结果中1的个数即为m和n的二进制表示中有几位不相同
        int count = 0;
        while(y != 0){
            count++;
            y = y&(y-1); //一个数n   n&(n-1)的结果将n的二进制表示中最后一个1变成0
        }
        return count;
        
    }

 

4.不使用中间变量交换m和n的值

异或

n^n = 0

n^0 = n

n^1 = ~n

m^n^m = m^m^n = n

    //不使用临时变量,交换n和m
    public void exchangeMandN(int m,int n){
        System.out.println("m:"+m+"--"+"n:"+n);
        m = m^n;
        n = m^n; // n = m^n^n
        m = m^n; // m = m^n^m
        System.out.println("m:"+m+"--"+"n:"+n);
    }