highestOneBit()方法
highestOneBit()方法的功能是获取数字的二进制中最高位1所对应的权值。
例如987654321的二进制是0011 1010 1101 1110 0110 1000 1011 0001,从右往左数最后一个"1"的位置是第30位,返回的十进制值就是2^(30-1),对应的二进制值也就是0010 0000 0000 0000 0000 0000 0000 0000。
该方法的源码及注释如下:
/**
* 如果是负数, 则返回 -2147483648:【1000,0000,0000,0000,0000,0000,0000,0000】(二进制表示的数)
* 如果是0,则返回0
* 如果是正数,则返回从左往右数第一个"1"(从右往左数最后一个"1")所表示的权值
* 例如987654321的二进制是0011 1010 1101 1110 0110 1000 1011 0001,从右往左数最后一个"1"的位置是第30位,返回的值就是2^(30-1)
*
* @param i 待查找的int类型数值
* @return 返回从左到右第一个1所表示的权值
*/
public static int highestOneBit(int i) {
// 思路就是不停得到右移再或运算,使得i最后变成从最高位1开始后面全是1
// 因为int类型的数为32位,考虑最坏的情况就是最高位是1,那么就需要移动31位让最高位1之后的所有位变成1
// 让最高位1之后的1位变成1
i |= (i >> 1);
// 让最高位1之后的3位(注意:3=1+2)变成1
i |= (i >> 2);
// 让最高位1之后的7位(注意:7=1+2+4)变成1
i |= (i >> 4);
// 让最高位1之后的15位(注意:15=1+2+4+8)变成1
i |= (i >> 8);
// 让最高位1之后的31位(注意:31=1+2+4+8+15)变成1
i |= (i >> 16);
// 最后这个减法就可以去除除了最高位1之后的所有1
return i - (i >>> 1);
}
该方法的代码执行过程如下:
/*
i=987654321,对应二进制(最高位是符号位)是0 011 1010 1101 1110 0110 1000 1011 0001
①i |= (i >> 1);
i=0011 1010 1101 1110 0110 1000 1011 0001
i>>1=0001 1101 0110 1111 0011 0100 0101 1000
i|=(i>>1)=0011 1111 1111 1111 0111 1100 1111 1001
②i |= (i >> 2);
i=0011 1111 1111 1111 0111 1100 1111 1001
i>>2=0000 1111 1111 1111 1101 1111 0011 1110
i|=(i>>2)=0011 1111 1111 1111 1111 1111 1111 1111
③i |= (i >> 4);
i=0011 1111 1111 1111 1111 1111 1111 1111
i>>4=0000 0011 1111 1111 1111 1111 1111 1111
i|=(i>>4)=0011 1111 1111 1111 1111 1111 1111 1111
④i |= (i >> 8);
i=0011 1111 1111 1111 1111 1111 1111 1111
i>>8=0000 0000 0011 1111 1111 1111 1111 1111
i|=(i>>8)=0011 1111 1111 1111 1111 1111 1111 1111
⑤i |= (i >> 16);
i=0011 1111 1111 1111 1111 1111 1111 1111
i>>16=0000 0000 0000 0000 0011 1111 1111 1111
i|=(i>>16)=0011 1111 1111 1111 1111 1111 1111 1111
⑥return i - (i >>> 1);
i=0011 1111 1111 1111 1111 1111 1111 1111
i>>>1=0001 1111 1111 1111 1111 1111 1111 1111
i-(i>>>1)=0010 0000 0000 0000 0000 0000 0000 0000
*/
lowestOneBit()方法
lowestOneBit()方法的功能是获取数字的二进制中最低位1所对应的权值。
例如数字8的二进制是0000 0000 0000 0000 0000 0000 0000 1000的结果是2^(4-1)=8。
该方法的源码及注释如下:
/**
* 在数值i的二进制表示中,除去符号位,从低(右)到高(左)找到第一个为1的位置p,返回数值为2的(p-1)次方。
* 如果数值i的二进制表示中除去符号位没有1,则返回0。
* 例如数字8的二进制是0000 0000 0000 0000 0000 0000 0000 1000的结果是2^3=8
*
* @param i 待查找的int类型数值
* @return 返回从右到左第一个1所表示的权值
*/
public static int lowestOneBit(int i) {
/*
例如数字8的二进制是0000 0000 0000 0000 0000 0000 0000 1000
那么-8的二进制是 1111 1111 1111 1111 1111 1111 1111 1000
那么8&-8结果是 0000 0000 0000 0000 0000 0000 0000 1000
所以最后的结果是 (0000 0000 0000 0000 0000 0000 0000 1000)2=(8)10
注:括号外面的数字表示进制,2表示二进制,10表示10进制,即二进制1000转换成十进制是8。注意,无论是正数还是负数,都是补码参与运算
*/
return i & -i;
}