Full Version : Log Routine in Assembler
avr >>COMPUTER MATH >>Log Routine in Assembler


JackRB- 05-18-2006
Does anyone know where I can find a good Log-base-two routine in assembler for small unsigned integers like 8 or 16 bits?

Just a generic routine would be good I can translate it.

Or perhaps even just a routine that will indicate the nearest power-of-two either above or below might work.



shg- 05-29-2006
It's quite simple...
All You need is to count the number of leading zeros. and substract the result from number of bits.
A number of "count leading zeros" (oftern simply called clz()) routines exists, but most of them are optimized for 16, or 32 bits architectures.
On AVR i think that "brute force" method will perform quite well, and it's very small.

This routine will return log2(x) rounded to the higher integer i.e. ceil(log2(x)) The result of log2(x) when x tends to 0+ is -infinity, but this routine returns zero instead.

CODE
int_log2(x)
nlz=NUMBER_OF_BITS
loop:
 x = x << 1 /* most significant bit into carry */
 if Carry=1 then return nlz
 nlz = nlz-1
 if nlz = 0 then return 0
goto loop


here is one of the optimized ways (just an idea how it works).
in C this time, example for 16 bits.
CODE
unsigned int intlog2(unsigned int x) {
int log2=16;
 if((x & 0x00ff) == 0) {
   log2 -= 8;
   x <<= 8;
 }
 if((x & 0x0fff) == 0) {
   log2 -= 4;
   x <<= 4;
 }
 if((x & 0x3fff) == 0) {
   log2 -= 2;
   x <<= 2;
 }
 if((x & 0x7fff) == 0) {
   log2 -= 1;
   x <<= 1;
 }
 if(x == 0)
   return(0);

 return(log2);
}



Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.