9

If you have the binary number 10110 how can I get it to return 11111? e.g a new binary number that sets all bits to 1 after the first 1, there are some likewise examples listed below:

101 should return 111 (3 bit length) 011 should return 11 (2 bit length) 11100 should be return 11111 (5 bit length) 101010101 should return 111111111 (9 bit length)

How can this be obtained the easiest way in Java? I could come up with some methods but they are not very "pretty".

1

4 Answers 4

13

My try: Integer.highestOneBit(b) * 2 - 1

Sign up to request clarification or add additional context in comments.

3 Comments

Hmmm.. Looks like I can't post the link. SO doesn't like brackets.
Wow, had no idea Java had this function... this is definitely most eleagant here.
7

You could use this code:

int setBits (int value)
{
    value |= (value >> 1);
    value |= (value >> 2);
    value |= (value >> 4);
    value |= (value >> 8);
    value |= (value >> 16);
    return value;
}

The idea is that leftmost 1 will get copied to all positions on the right.

EDIT: Also works fine with a negative value. If you replace int with long, add one extra |= statement: value |= (value >> 32). In general, last shift must be a power of 2 that is at least half of value size in bits.

2 Comments

What's especially nice with that algorithm is that it reuses the prior operations. Naively i would just have done 32 shifts.
If you look at the implementation for Integer#highestOneBit() in the JDK, you'll see the same algorithm, though the last step is tailored deliver only single one bit, requiring the undoing captured in hleinone's answer.
6

Haven't tested, but something like this should be okay:

long setBits(long number) {
  long n = 1;
  while (n <= number) n <<= 1;
  return n - 1;
}

2 Comments

This won't work if number is negative. It will be fast if number is usually small, but slow if number is about uniformly distributed on its range.
True about negatives, I didn't think about that. And it would be faster on the average if I started from the other end. But 63 iterations (max) aren't really that slow; and the answer was off the top of my head. Obviously, hleinone's solution blows it out of the water... :)
0

Not most efficient, but simplest,

    int i = (1 << (int)(Math.log(n)/Math.log(2)+1)) - 1;

It will work for first 31 bit of int and first 63 bit for long.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.