Find the N-th power of 2 closest to a number

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.

reference resources

Find the power of 2 of the nearest number n

Tags: Java Algorithm data structure

Posted on Thu, 28 Oct 2021 01:58:16 -0400 by hd_webdev