Previous power of 2

后端 未结 11 1414
一整个雨季
一整个雨季 2020-11-30 05:42

There is a lot of information on how to find the next power of 2 of a given value (see refs) but I cannot find any to get the previous power of two.

The only way I f

相关标签:
11条回答
  • 2020-11-30 06:25

    Probably the simplest approach (for positive numbers):

    // find next (must be greater) power, and go one back
    p = 1; while (p <= n) p <<= 1; p >>= 1;
    

    You can make variations in many ways if you want to optimize.

    0 讨论(0)
  • 2020-11-30 06:27

    If you can get the next-higher power of 2, the next-lower power of 2 is either that next-higher or half that. It depends on what you consider to be the "next higher" for any power of 2 (and what you consider to be the next-lower power of 2).

    0 讨论(0)
  • 2020-11-30 06:27

    What about

    if (tt = v >> 16)
    {
       r = (t = tt >> 8) ? 0x1000000 * Table256[t] : 0x10000 * Table256[tt];
    }
    else 
    {
      r = (t = v >> 8) ? 0x100 * Table256[t] : Table256[v];
    }
    

    It is just modified method from http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup. This require like 7 operations and it might be faster to replace multiplications whit shift.

    0 讨论(0)
  • 2020-11-30 06:28
    uint32_t previous_power_of_two( uint32_t x ) {
        if (x == 0) {
            return 0;
        }
        // x--; Uncomment this, if you want a strictly less than 'x' result.
        x |= (x >> 1);
        x |= (x >> 2);
        x |= (x >> 4);
        x |= (x >> 8);
        x |= (x >> 16);
        return x - (x >> 1);
    }
    

    Thanks for the responses. I will try to sum them up and explain a little bit clearer. What this algorithm does is changing to 'ones' all bits after the first 'one' bit, cause these are the only bits that can make our 'x' larger than its previous power of two. After making sure they are 'ones', it just removes them, leaving the first 'one' bit intact. That single bit in its place is our previous power of two.

    0 讨论(0)
  • 2020-11-30 06:29

    This is my current solution to find the next and previous powers of two of any given positive integer n and also a small function to determine if a number is power of two.

    This implementation is for Ruby.

    class Integer
    
      def power_of_two?
        (self & (self - 1) == 0)
      end
    
      def next_power_of_two
        return 1 if self <= 0
        val = self
        val = val - 1
        val = (val >> 1) | val
        val = (val >> 2) | val
        val = (val >> 4) | val
        val = (val >> 8) | val
        val = (val >> 16) | val
        val = (val >> 32) | val if self.class == Bignum
        val = val + 1
      end
    
      def prev_power_of_two
       return 1 if self <= 0
       val = self
       val = val - 1
       val = (val >> 1) | val
       val = (val >> 2) | val
       val = (val >> 4) | val
       val = (val >> 8) | val
       val = (val >> 16) | val
       val = (val >> 32) | val if self.class == Bignum
       val = val - (val >> 1)
      end
    end
    

    Example use:

    10.power_of_two? => false
    16.power_of_two? => true
    10.next_power_of_two => 16
    10.prev_power_of_two => 8
    

    For the previous power of two, finding the next and dividing by two is slightly slower than the method above.

    I am not sure how it works with Bignums.

    0 讨论(0)
  • 2020-11-30 06:32

    Below code will find the previous power of 2:

    int n = 100;
        n /= 2;//commenting this will gives the next power of 2
        n |= n>>1;
        n |= n>>2;
        n |= n>>4;
        n |= n>>16;
    
    System.out.println(n+1);
    
    0 讨论(0)
提交回复
热议问题