Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How bit manipulation works?

There was a question asked:

"Presented with the integer n, find the 0-based position of the second rightmost zero bit in its binary representation (it is guaranteed that such a bit exists), counting from right to left.

Return the value of 2position_of_the_found_bit."

I had written below solution which works fine.

int secondRightmostZeroBit(int n) {
  return (int)Math.pow(2,Integer.toBinaryString(n).length()-1-Integer.toBinaryString(n).lastIndexOf('0',Integer.toBinaryString(n).lastIndexOf('0')-1))  ;
}

But below was the best voted solution which I also liked as it has just few characters of codding and serving the purpose, but I could not understand it. Can someone explain how bit manipulation is helping to achieve it .

int secondRightmostZeroBit(int n) {
  return ~(n|(n+1)) & ((n|(n+1))+1) ;
}
like image 979
Learner Avatar asked Apr 20 '17 05:04

Learner


People also ask

Is bit manipulation difficult?

Bit manipulation, in some cases, can obviate or reduce the need to loop over a data structure and can give many-fold speed-ups, as bit manipulations are processed in parallel, but the code can become more difficult to write and maintain.

How do you solve a bit manipulation question?

This can be solved based on the following fact: If a number N is a power of 2, then the bitwise AND of N and N-1 will be 0. But this will not work if N is 0. So just check these two conditions, if any of these two conditions is true.

How do bit operations work?

A bitwise operation operates on two-bit patterns of equal lengths by positionally matching their individual bits. For example, a logical AND (&) of each bit pair results in a 1 if both the first AND second bits are 1. If only one bit is a 1, the result is 0.

Is bit manipulation an algorithm?

Bit manipulation is the act of algorithmically manipulating bits using bit-level (bitwise) operations. These bitwise operations are the heart of bit manipulation. They are primitive, fast actions that are used in improving the efficiency of a program.


1 Answers

Consider some number having at least two 0 bits. Here is an example of such a number with the 2 rightmost 0 bits marked (x...x are bits we don't care about which can be either 0 or 1, and 1...1 are the sequences of zero or more 1 bits to the right and to the left of the rightmost 0 bit) :

x...x01...101...1 - that's n

If you add 1 to that number you get :

x...x01...110...0 - that's (n+1)

which means the right most 0 bit flipped to 1

therefore n|(n+1) would give you:

x...x01...111...1 - that's n|(n+1)

If you add 1 to n|(n+1) you get:

x...x100........0 - that's (n|(n+1))+1

which means the second right most 0 bit also flips to 1

Now, ~(n|(n+1)) is

y...y10.........0 - that's ~(n|(n+1))

where each y bit is the inverse of the corresponding x bit

therefore ~(n|(n+1)) & ((n|(n+1))+1) gives

0...010.........0

where the only 1 bit is at the location of the second rightmost 0 bit of the input number.

like image 130
Eran Avatar answered Sep 20 '22 13:09

Eran