Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Previous power of 2

Tags:

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 find so far is to keep a table with all power of two up to 2^64 and make a simple lookup.

  • Acius' Snippets
  • gamedev
  • Bit Twiddling Hacks
  • Stack Overflow
like image 369
Horacio Avatar asked Apr 21 '10 01:04

Horacio


People also ask

How do you find previous powers of 2?

The idea is to set all bits on the right-hand side of the most significant set bit to 1 and then drop all but the last set bit from n so that it becomes equal to the previous power of two. For instance, consider number 20. We convert its binary representation 00010100 to 00011111 .

What is a power of 2?

A power of two is a number of the form 2n where n is an integer, that is, the result of exponentiation with number two as the base and integer n as the exponent.

How do you find the power of 2 of a number?

Another solution is to keep dividing the number by two, i.e, do n = n/2 iteratively. In any iteration, if n%2 becomes non-zero and n is not 1 then n is not a power of 2. If n becomes 1 then it is a power of 2.


2 Answers

From Hacker's Delight, a nice branchless solution:

uint32_t flp2 (uint32_t x)
{
    x = x | (x >> 1);
    x = x | (x >> 2);
    x = x | (x >> 4);
    x = x | (x >> 8);
    x = x | (x >> 16);
    return x - (x >> 1);
}

This typically takes 12 instructions. You can do it in fewer if your CPU has a "count leading zeroes" instruction.

like image 101
Paul R Avatar answered Sep 18 '22 17:09

Paul R


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.

like image 44
Vladius Avatar answered Sep 20 '22 17:09

Vladius