Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using bit manipulation to tell if an unsigned integer can be expressed in the form 2^n-1

To test if an unsigned integer is of the form 2^n-1 we use:

x&(x+1)

What is that supposed to equal? That is,

x&(x+1) == ?
like image 246
dato datuashvili Avatar asked Jun 20 '10 18:06

dato datuashvili


2 Answers

A number of the form 2^n-1 will have all of the bits up to the nth bit set. For example, 2^3-1 (7) is:

0b0111

If we add one to this, we get 8:

0b1000

Then, performing a bitwise and, we see that we get zero, because no bit is set on in both numbers. If we start with a number not of the form 2^n+1, then the result will be nonzero.

like image 132
James McNellis Avatar answered Oct 13 '22 05:10

James McNellis


In complement to the existing answers, here is a short explanation of why numbers x that are not of the form 0b00000 (zero) or 0b0111..11 (all lowest digits set, these are all the numbers 2^n-1 for n>0) do not have the property x&(x+1) == 0.

For a number x of the form 0b????1000..00, x+1 has the same digits as x except for the least significant bit, so x & (x+1) has at least one bit set, the bit that was displayed as being set in x. By way of shorter explanation:

x       0b????1000..00
x+1     0b????1000..01
x&(x+1) 0b????10000000

For a number x of the form 0b????10111..11:

x       0b????10111..11
x+1     0b????110000000
x&(x+1) 0b????10000..00

In conclusion, if x is not either zero or written in binary with all lowest digits set, then x&(x+1) is not zero.

like image 24
Pascal Cuoq Avatar answered Oct 13 '22 04:10

Pascal Cuoq