5

I want to calculate the smallest integer with exactly k bits set, that is greater than another integer x.

For example if x = 1001010 then for k=2, the answer should be 1010000 for k=4, the answer should be 1001011 and for k=5 the answer is 1001111

I think that one would need to set at least as many bits as the leftmost bits set in the integer x, and then choose between setting the MSB-side bit adjacent to the next leftmost set bit in x, or setting the next leftmost set bit and then look at setting the bits following that by repeating the same process; all the while counting the bits left out of the k.

I am not sure if this is the correct approach.

adi
  • 580
  • 2
  • 12
  • providing sample input/output will make your question much more easier to understand. Do you mean the two integers should have same number of bits set? – xvatar Jun 15 '12 at 20:16
  • @xvatar I think `x` and `k` are both inputs for the program, that is, `x = 1001010`, `k = 2` would return `1010000` – ffao Jun 15 '12 at 20:19
  • should the answer contain exactly k bits set, or at least k bits set? – Colin D Jun 15 '12 at 20:25
  • @xvatar I realized I should have been more clear in my question. I have made the appropriate changes. – adi Jun 16 '12 at 14:48
  • @EitanT No this isn't homework :-) . This occurred to me while I was solving a related problem that I had been asked in an interview. – adi Jun 16 '12 at 14:51

1 Answers1

6
++x;

while (popcnt(x) > k)
{
    // Substitute the least-significant group of bits
    // with single bit to the left of them
    x |= x-1;
    ++x;
}

unsigned bit = 1;
while (popcnt(x) < k)
{
    x |= bit;
    bit <<= 1;
}

Second loop may be optimized:

for (i = k - popcnt(x); i != 0; --i)
{
    // Set the lowest non-set bit
    x |= x+1;
}
Evgeny Kluev
  • 24,287
  • 7
  • 55
  • 98
  • @ffao: there are lots of such tricks in "The art of computer programming, vol 4A" by D.Knuth. Or in ["Matters Computational"](http://www.jjj.de/fxt/#fxtbook). – Evgeny Kluev Jun 15 '12 at 20:54
  • @EvgenyKluev Thank you for the answer and for introducing me to gcc popcnt. I didn't know about that and would have probably written a loop to count the set bits. – adi Jun 16 '12 at 15:00