PIC Microcontoller Power of 2 Check Math Methods

Test if a value is a power of two.

a function that returns zero if INDF is a power of two, else returns non-zero.

Dmitry A. Kiryashov [nzews at MAIL.RU] says:

        decf    INDF,F  ;0/1/others -> Z=0/Z=1/Z=0
        incfsz  INDF,W  ;0?
        andwf   INDF,W
        return

Was =0 returning Z=0

Was !=0 and power of 2 returning Z=1

Was !=0 and not a power of 2 returning Z=0

Disadvantage: INDF is decremented in this case.

Wouter adds:

the formula is
( x - 1 ) & ( x | 0x80 )

explanation:

verification:

#include <stdio.h>

int f( int x ){
   return ( 0xFF & ( (x - 1) & ( x | 0x80 ) ) );
}

int ones( int x ){
   int n = 0;
   while( x > 0 ){
      if( x & 1 > 0 ){
         n++;
      }
      x = x >> 1;
   }
   return n;
}

int main( void ){
   int i, j, k;
   for( i = 0; i < 256; i ++ ){
      j = f( i );
      k = ones( i );
      printf( "%2X %2X %2X %d\n", i, j, k, ( k == 1 ) == ( j == 0 ) );
   }
   return 0;
}

Scott Dattalo says:

But it'd probably make more sense to just make this a macro:
is_power_of_2  MACRO  x
  decf  x,w
  bsf   x,7
  andwf x,w

 end

Both W and the Z bit contain the result.

If you don't wish the register under test to be modified then this is probably the best solution:

is_power_of_2  MACRO  x

   decf   x,w
   movf   x,f
   skpz
    andwf x,w
 end

or this:

is_power_of_2  MACRO  x

   movlw  -1
   addwf  x,w
   skpnc
    andwf x,w

 end

Questions: