3

How do you find the largest power of 2 a number is divisible by using logic function

for example 144 is divisible by 16 which is 2^4.

How would one do this.

I know 144 in binary is 1001 0000 and I have to use a bitwise function.

But what would I use (and or andn orn ?) or perhaps something else and what can I use as my mask?

I know you have to look at the right most number to tell if it is divisible by 2.

Any help is appreciated

1 Answers1

2

I would go with n & -n or with n & (~n + 1), in case you are worried about running across one's complement arithmetic, given the latter works with both arithmetics.

E.g.,

> 144 & (~144 + 1)
< 16

Now a short explanation.

The bitwise NOT (i.e., ~ operator) of a number n gives -(n + 1). It inverts all the bits of n. The number 2 is represented by 00000010 while its negation is 11111101 which equals to -3 (i.e., conversion from two's complement to decimal, see the two's complement representation of signed numbers).

Do not to confuse it with logical negation.

E.g., ~144 = -(144 + 1) = -145.

The bitwise AND (i.e., & operator) compares two bits of the inputs and generates a result of 1 if both are 1, otherwise it returns 0.

Now the main topic.

This is an old tricks that gives the highest power of 2 that n is divisible by. This means that it returns a number with a single one bit, specifically the bottom bit that was set in n.

For example the binary representation of 144 is 010010000. Its bottom 1 bit is the bit in fourth position (counting backward from right and starting at position 0). Thus the higher power of 2 that divides 144 is 16 (i.e., 00010000).

144 & (~144 + 1) = 144 & -144 = 16
 16 & ( ~16 + 1) =  16 & - 16 = 16
 10 & ( ~10 + 1) =  10 & - 10 =  2
 12 & ( ~12 + 1) =  12 & - 12 =  4
 11 & ( ~11 + 1) =  11 & - 11 =  1
  3 & ( ~ 3 + 1) =   3 & -  3 =  1

Note that if n is not divisible by any power of 2 it returns 1.

Why it works?

The negative of n is produced by inverting its bits via ~, then adding 1 (again, see two's complement definition). This sum causes every 1 bit (starting from the bottom) to overflow until a 0 bit is encountered (let us call it the bit x). Here the overflow process stops, leaving remaining bits (those beyond the current x bit) unchanged. Thus performing & between n and its inverse will result in a binary string containing only the x bit.

An example follows.

010010000 | +144 ~
----------|-------
101101111 | -145 +
        1 |
----------|-------
101110000 | -144 

101110000 | -144 & 
010010000 | +144
----------|-------
000010000 |   16
leodido
  • 912
  • 7
  • 21