views:

960

answers:

9

If I have a integer number n. How can I find the next number k > n : k = 2^i, with some i element of N By bitwise shifting or logic.

Example: If I have n=123 how can I find k=128 which is a power of two: 2^7(=i) and not 124 which is only divisible by two. It should be simple, but it eludes me.

+1  A: 

Here's a logic answer:

function getK(int n)
{
  int k = 1;
  while (k < n)
    k *= 2;
  return k;
}
JustLoren
A: 
function Pow2Thing(int n)
{
    x = 1;
    while (n>0)
    {
        n/=2;
        x*=2;
    }
    return x;
}
rikh
+17  A: 

For 32-bit integers, this is a simple and straightforward route:

unsigned int n;

n--;
n |= n >> 1;   // Divide by 2^k for consecutive doublings of k up to 32,
n |= n >> 2;   // and then or the results.
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n++;           // The result is a number of 1 bits equal to the number
               // of bits in the original number, plus 1. That's the
               // next highest power of 2.

Here's a more concrete example. Let's take the number 221, which is 11011101 in binary:

n--;           // 1101 1101 --> 1101 1100
n |= n >> 1;   // 1101 1101 | 0110 1110 = 1111 1111
n |= n >> 2;   // ...
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;  // 1111 1111 | 1111 1111 = 1111 1111
n++;           // 1111 1111 --> 1 0000 0000

There's one bit in the ninth position, which represents 2^8, or 256, which is indeed the next largest power of 2. Each of the shifts overlaps all of the existing 1 bits in the number with some of the previously untouched zeroes, eventually producing a number of 1 bits equal to the number of bits in the original number. Adding one to that value produces a new power of 2.

Another example; we'll use 131, which is 10000011 in binary:

n--;           // 1000 0011 --> 1000 0010
n |= n >> 1;   // 1000 0010 | 0100 0010 = 1100 0011
n |= n >> 2;   // 1100 0011 | 0011 0000 = 1111 0011
n |= n >> 4;   // 1111 0011 | 0000 1111 = 1111 1111
n |= n >> 8;   // ... (At this point all bits are 1, so further bitwise-or
n |= n >> 16;  //      operations produce no effect.)
n++;           // 1111 1111 --> 1 0000 0000

And indeed, 256 is the next highest power of 2 from 131.

If the number of bits used to represent the integer is itself a power of 2, you can continue to extend this technique efficiently and indefinitely (for example, add a n >> 32 line for 64-bit integers).

John Feminella
Beat me to it. +1
Pesto
Ah great thanks! I had a hard time to understand why you could double k every step, but since you "double" every '1' it became obvious. Thanks for the example.
AndreasT
@AndreasT: No problem! (BTW, to see why you need to go all the way up to n >> 16, consider what happens if n is already a power of 2. You'll only have a single 1 bit that needs to cover all of the previous bits, which is why all the shifting is necessary.)
John Feminella
+1 yes, good trick, I like it :) Some more bit-twiddling tricks can be found here: http://graphics.stanford.edu/~seander/bithacks.html
zxcat
A: 

What about something like this:

int pot = 1;
for (int i = 0; i < 31; i++, pot <<= 1)
    if (pot >= x)
        break;
Eric
+1  A: 

A more mathematical way, without loops:

public static int ByLogs(int n)
{
    double y = Math.Floor(Math.Log(n, 2));

    return (int)Math.Pow(2, y + 1);
}
DanDan
Thanks. But I was searching for a "bit-twiddle" way. ;-)
AndreasT
+1, not what the OP wanted, but strangely enough I needed an answer that would fit in a single inline expression: `2 ^ (floor(log(x) / log(2)) + 1)`
zildjohn01
+2  A: 

More generally, see the book Hacker's Delight, by Henry S. Warren, Jr. Full of useful bit-twiddling algorithms to address problems such as this.

Cesar Providenti
+1  A: 

Here's a wild one that has no loops, but uses an intermediate float.

//  compute k = nextpowerof2(n)

if (n > 1) 
{
  float f = (float) n;
  unsigned int const t = 1U << ((*(unsigned int *)&f >> 23) - 0x7f);
  k = t << (t < n);
}
else k = 1;

This, and many other bit-twiddling hacks, including the on submitted by John Feminella, can be found here.

I. J. Kennedy
wtf! 8-) , will check it out. Thx
AndreasT
A: 

You just need to find the most significant bit and shift it left once. Here's a Python implementation. I think x86 has an instruction to get the MSB, but here I'm implementing it all in straight Python. Once you have the MSB it's easy.

>>> def msb(n):
...     result = -1
...     index = 0
...     while n:
...         bit = 1 << index
...         if bit & n:
...             result = index
...             n &= ~bit
...         index += 1
...     return result
...
>>> def next_pow(n):
...     return 1 << (msb(n) + 1)
...
>>> next_pow(1)
2
>>> next_pow(2)
4
>>> next_pow(3)
4
>>> next_pow(4)
8
>>> next_pow(123)
128
>>> next_pow(222)
256
>>>
FogleBird
+5  A: 

There is actually a assembly solution for this (since the 80386 instruction set).

You can use the BSR (Bit Scan Reverse) instruction to scan for the most significant bit in your integer.

bsr scans the bits, starting at the most significant bit, in the doubleword operand or the second word. If the bits are all zero, ZF is cleared. Otherwise, ZF is set and the bit index of the first set bit found, while scanning in the reverse direction, is loaded into the destination register

(Extracted from: http://dlc.sun.com/pdf/802-1948/802-1948.pdf)

And than inc the result with 1.

so:

bsr ecx, eax  //eax = number
jz  @zero
mov eax, 2    // result set the second bit (instead of a inc ecx)
shl eax, ecx  // and move it ecx times to the left
ret           // result is in eax

@zero:
xor eax, eax
ret
Davy Landman
that is cool! thx!
AndreasT