The first method
public class TestClosest2NthPower { public static void main(String[] args) { System.out.println(test(-1));//1 System.out.println(test(1));//1 System.out.println(test(-1));//1 System.out.println(test(10));//16 System.out.println(test(16));//16 System.out.println(test(Integer.MAX_VALUE));//2^30 } private static int test(int target) { //The maximum value of int type is (2 ^ 31) - 1, so the maximum value that the target can get is 2 ^ 30 int MAXIMUM = 1 << 30; if (target >= MAXIMUM) { return MAXIMUM; } int result = 1; while (result < target) { result *= 2; } return result; } }
It is equivalent to finding the closest number among the 31 numbers of the 0th power of 2 and the 30th power of 2.
[2^0,2^1 ... 2^30]
The second method
public class TestClosest2NthPower2 { public static void main(String[] args) { System.out.println(test(-1));//1 System.out.println(test(1));//1 System.out.println(test(-1));//1 System.out.println(test(10));//16 System.out.println(test(16));//16 System.out.println(test(Integer.MAX_VALUE));//2^30 } private static int test(int target) { //The maximum value of int type is (2 ^ 31) - 1, so the maximum value that the target can get is 2 ^ 30 int MAXIMUM = 1 << 30; if (target >= MAXIMUM) { return MAXIMUM; } int temp = target - 1; temp |= temp >> 1; temp |= temp >> 2; temp |= temp >> 4; temp |= temp >> 8; temp |= temp >> 16; return (temp < 0) ? 1 : temp + 1; } }
Example analysis
Take 129 as an example (the effect can be seen more clearly). First subtract 1 to 128, and the binary representation is
00000000 00000000 00000000 10000000
Shift right 1 bit
00000000 00000000 00000000 01000000
Bitwise OR
00000000 00000000 00000000 11000000
It ensures that the first two bits are 1, and so on. It can ensure that the first 1 and all subsequent bits are 1
00000000 00000000 00000000 11111111
Add one more
00000000 00000000 00000001 00000000
The decimal representation is 256.
Core principles
The core principle is to set the first 1 and all subsequent bits of the binary representation of a number minus 1 to 1, and then add 1. In this way, the number obtained is the N-power of 2, which is equivalent to the highest 1 to the left, and all subsequent bits are set to 0.
Why subtract 1 first
In order to be compatible with the case where a number is already to the nth power of 2. Take the fourth power 16 of 2 as an example, subtract 1 to 15, and the final operation result is 16. If this number is not the N-power of 2, such as 15, in fact, the correct result 16 can be obtained by subtracting 1 or not.
Usage scenario
This method is used when initializing the capacity of workQueues in the constructor of ForkJoinPool.
The third method
public class TestClosest2NthPower3 { public static void main(String[] args) { System.out.println(test(-1));//1 System.out.println(test(1));//1 System.out.println(test(-1));//1 System.out.println(test(10));//16 System.out.println(test(16));//16 System.out.println(test(Integer.MAX_VALUE));//2^30 } private static int test(int target) { //The maximum value of int type (2 ^ 31) - 1, so the maximum value that the target can get is 2 ^ 30 int MAXIMUM = 1 << 30; if (target >= MAXIMUM) { return MAXIMUM; } int n = -1 >>> Integer.numberOfLeadingZeros(target - 1); return (n < 0) ? 1 : n + 1; } }
Example analysis
Take 129 as an example (the effect can be seen more clearly). First subtract 1 to 128, and the binary representation is
00000000 00000000 00000000 10000000
Use the numberOfLeadingZeros() method of Integer to find that the number of leading zeros is 24, and the binary representation of - 1 is
11111111 11111111 11111111 11111111
Unsigned right shift 24 bits
00000000 00000000 00000000 11111111
Add one more
00000000 00000000 00000001 00000000
The decimal representation is 256.
Core principles
Similar to the principle of the previous method, it is also to set the first 1 and all subsequent bits of the binary representation of a number minus 1 to 1, and then add 1.
Usage scenario
This method refers to the algorithm for calculating the capacity in HashMap.