给定一个非负整数num,
如何不用循环语句,
返回>=num,并且离num最近的,2的某次方
这个如果使用循环或者递归方法很容易解决,但是如果不用循环语句的话怎么办呢
package dataStructure.bigFactory;
/**
* 给定一个非负整数num,
* 如何不用循环语句,
* 返回>=num,并且离num最近的,2的某次方
*/
public class NextPowerOfTwo {
public static int getNextPowerOfTwo(int num) {
num = num - 1;
//这一步是把num的第一个1的下一位也变成1(第一个1开始2位都是1)
num |= num >>> 1;
//这一步是把num的第一个1的往后的三四位都变成1(第一个1开始的4位都是1)
num |= num >>> 2;
//这一步是把num的第一个1的往后的五六七八位都变成1(第一个1开始的8位都是1)
num |= num >>> 4;
//这一步是把num的第一个1的往后的9~16位都变成1(第一个1开始的16位都是1)
num |= num >>> 8;
//这一步是把num的第一个1的往后的17~32位都变成1(第一个1开始的32位都是1)
num |= num >>> 16;
//这些变1的过程中如果出现了最高位为1的情况,说明变成了负数了
return num + 1 <= 0? 1 : num + 1;
}
public static void main(String[] args) {
int num = Integer.MAX_VALUE;
int nextPowerOf2 = getNextPowerOfTwo(num);
System.out.println(nextPowerOf2);
}
}
里面重点的语句都有详细的注释,我们画图模拟一下这个过程,先来个简单的
随意找个复杂的数
n>>>1是把num的第一个1的下一位也变成1(第一个1开始2位都是1)
n>>>2是把num的第一个1的往后的三四位都变成1(第一个1开始的4位都是1)
n>>>4是把num的第一个1的往后的五六七八位都变成1(第一个1开始的8位都是1)
n>>>8是把num的第一个1的往后的9~16位都变成1(第一个1开始的16位都是1)
n>>>16是把num的第一个1的往后的17~32位都变成1(第一个1开始的32位都是1)
int类型只有32位,第一位是符号位,我们这里是正数,所以第一个1顶多出现在31位,不过无所谓了。
注意最后返回的时候的边界处理