任意给定一个数,求比小的,最大的2的整数次幂(一个神级算法)
来自外国一位天才手中的高效算法
例如: 给定一个数 17,那么可以返回2的4次方,即返回16,
给定一个数 7,返回2的2次方,即放回4
只采用右移和或运算,执行效率高
1.此方法在java中的Integer类中:
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
- (1)举一个例子:
例如 i = 17
17 0001 0001
>>1 0000 1000 左移一位
| 0001 1001 或
>>2 0000 0110
| 0001 1111
>>4 0000 0001
| 0001 1111
>>8 0000 0000 (右移后出现全0就可以停止了,因为再全0的数再进行右移还是0,任何数和0或之后都是他本身)
| 0001 1111
>16 0000 0000 (这一步基本可以停止了)
| 0001 1111
>>1 0000 1111
- 0001 0000 -------->16,小于17的最大的2的整数次幂为16
(2)规律(举了一个特殊的例子):
假定给一个数:
001* ****
>>1 0001 ****
> | 0011 ****
>>2 0000 11**
| 0011 11**
>>4 0000 0011
| 0011 1111
>>8 0000 0000
| 0011 1111
>>1 0001 1111
- 0010 0000 ----->0010 0000 即是只保留最高位上的1,其低位全部去掉
3.由于这个算法只采用右移和或运算,所以执行效率很快,但这个算法估计只有天才才能想到
4.思考两个问题:
1.为什么右移的次数为1,2,4,8,16位?为什么不是其他?
2.int 类型的范围是4个字节 32位,1+2+4+8+16 =31?你有发现什么规律?