常用移位算法
- 给定值最高位1的权重
 - 给定值最低位1的权重
 - 给定值高位连续零的个数
 - 给定值低位连续零个数
 
给定值最高位1的权重
也就是给定值左侧。返回给定值左侧最大的2的次幂
 
//获取i最高位1代表的2次幂,最高位1代表的权值
 public static int highestOneBit(int i) {
        // HD, Figure 3-1
        i |= (i >>  1);//将第二高位置1
        i |= (i >>  2);//将第二高位之后的两位置1
        i |= (i >>  4);
        i |= (i >>  8);
        i |= (i >> 16);//所有位都置1了
        //此时的如果i+1就是i右侧最小的2次幂(HashMap)
        return i - (i >>> 1);//i左侧最大的2次幂
    }
 
给定值最低位1的权重

//获取i最低位的1所代表的值,即最低为位1代表的2的次幂。-i是i各位取反之后,加1。
// i=  1 1 0 0 1 0 1 0
//-------------
//-i=  0 0 1 1 0 1 1 0
//10,最低位1代表的值。
public static int lowestOneBit(int i) {
        // HD, Section 2-1
        return i & -i;
    }
 
计算整数的二进制表示中1的个数:通过多次执行 i = i & (i - 1),可以计算出一个整数中1的个数。每次执行 i & (i - 1) 操作,都会将 i 的最低位的1置为0,直到 i 变为0为止。
判断一个整数是否是2的幂:如果一个整数 i 是2的幂,那么它的二进制表示中只有一个1。通过执行 i & -i 操作,如果结果为 i,则表示 i 是2的幂;否则,表示 i 不是2的幂。
找到数组中唯一出现一次的元素:如果数组中除了一个元素外,其他元素都出现了两次,可以通过执行异或操作来找到唯一出现一次的元素。而执行异或操作的依据就是 i & -i 的结果。
给定值高位连续零的个数
最高位1前面连续零的个数。二分法:先看高16位
 
public static int numberOfLeadingZeros(int i) {
        // HD, Figure 5-6
        if (i == 0)//如果是0,32位全零
            return 32;
        int n = 1;
        /**无符号右移16位,如果等于0,高16位全零拿n+=16,再看低16位
        * i左移16位,推掉了高16位;低16位覆盖高16,此时对这16位折半,就右移
        * 24位,剩下的是原数的低16位的前8位,如果等于0,前24位都是0,n+=8。
        * i左移8位,低8位放到了最高位。对原数的低8位折半,右移28位,低8位的高四位,
        * 全0,前面28位都是0,n+=4。再看低4位,左移4位,低四位放在最高位上。折半,
        * 左移30位,剩下的是低四位的高两位,全零,前30位都是0,则n+=2。再看最低两位
        * 左移两位,最低两位在最高位上。折半,左移31,剩下最低位了,如果为0,不用计算
        * 一看是n=1就默认最低为0,计算过了。如果为1,那就计算多了所以-1
        */
        if (i >>> 16 == 0) { n += 16; i <<= 16; }
        if (i >>> 24 == 0) { n +=  8; i <<=  8; }
        if (i >>> 28 == 0) { n +=  4; i <<=  4; }
        if (i >>> 30 == 0) { n +=  2; i <<=  2; }
        //折半,左移31,剩下最低位了,如果为0,不用计算,一开始n=1就默认最低为0,
        //计算
        //过了。如果为1,那就计算多了所以-1
        n -= i >>> 31;
        return n;
    }
 
给定值低位连续零个数
 public static int numberOfTrailingZeros(int i) {
        // HD, Figure 5-14
        int y;
        if (i == 0) return 32;
        int n = 31;
        y = i <<16; if (y != 0) { n = n -16; i = y; }
        y = i << 8; if (y != 0) { n = n - 8; i = y; }
        y = i << 4; if (y != 0) { n = n - 4; i = y; }
        y = i << 2; if (y != 0) { n = n - 2; i = y; }
        return n - ((i << 1) >>> 31);
    }
                


















