circuitcellar.com
Magazine Support   Digital Library   Products & Services   Suppliers Directory 
 
 





 

May 2005, Issue 178

Test Your EQ

Answer 1—The function computes the integer square root of its argument, using a bitwise successive-approximation technique. The big advantage to this technique is that it requires only addition, shifting and logical or operations, and no multiplication or division. Rewritten with better variable names, it looks like the following:

uint16 SquareRoot (uint16 Number)
{
uint16 Root;
uint16 RootSquared;
uint16 Mask;
uint16 MaskSquared;
uint16 Test;
uint16 Power;
	
Root = 0;
RootSquared = 0;
Mask = 1 << (Precision - 1 );
MaskSquared = 1L << ( ( Precision - 1 ) << 1 );

for (Power = Precision; Power > 0; --Power) {
    Test = RootSquared + MaskSquared + ((uint16)Root << Power);
     if (Test <= Number) {
          RootSquared = Test;
          Root |= Mask;
    	}
    	Mask >>= 1;
    	MaskSquared >>= 2;
  	}

  	return Root;
}

Mathematically, it takes an initial guess, Root, and attempts to add an incremental value, Mask, to it. In order to see whether or not this new guess will exceed the given number, it’s necessary to square it. In symbolic terms, you need the result: 

(Root + Mask)2 

Multiplying this out, you get: 

Root2 + Mask2 + 2 × Root × Mask  

Note that the relationship between Mask and Power is initialized to: 

Mask = 2Power  – 1 

which is maintained as the loop executes. Therefore, 

2 × Mask = 2Power 

You can substitute this directly into the squaring operation: 

Root2 + Mask2 + Root × 2Power 

which is exactly what the "Test = ..." line in the code implements.

Contributor: David Tweed

   

E-mail eq@circuitcellar.com with questions or comments.

Back to Questions