Go to notes and algorithms index. ~ Go to home page.

integer_square_root() Find the square root of an integer value.


Integer version. Uses square root emulation formulae to do a quick good approximation of the desired result.

Because the square root curve is hard to emulate accross the whole range we want then I've had to split-up the ranges...and this highlights an interesting thing about the square root curve: that it is kind of fractal, or scalable, in nature. You'll see that the formulae used are essentially the same for each range, the only difference being that the numbers are appropriately larger for each range (but proportionally the same). So much so that I could have written this routine in a small neat loop, however there would be a little over-head in executing the loop instructions.

The routine doesn't even think about doing square roots of negative numbers -- for negative numbers it will just spit back the negative number it was given.




long integer_square_root2( long v_square )
   {  //  (c) Jon P 1999
   register long temp;
   temp = v_square;
   

   if ( temp > 1 )
      {
      if ( temp < 4 )
         {
         temp++;
         temp >>= 1;
         }
      else
         {
         if ( temp < 16 )
            {
            temp += 11;
            temp = temp / 6;
            }
         else
            {
            if ( temp < 64 )     //(temp & 0xFFFFFFC0) == 0    
               {
               temp += 96;
               temp = 1520 / temp;
               temp = 17 - temp;
               }
            else
               {
               if ( temp < 256 )
                  {
                  temp += 390;
                  temp = 12020 / temp;
                  temp = 34 - temp;
                  }
               else
                  {
                  if ( temp < 1024 )
                     {
                     temp += 1535;
                     temp = 95800 / temp;
                     temp = 69 - temp;
                     }
                  else
                     {
                     if ( temp < 4096 )
                        {
                        temp += 6185;
                        temp = 767232 / temp;
                        temp = 138 - temp;
                        }
                     else
                        {
                        if ( temp < 16384 )
                           {
                           temp += 24810;
                           temp = 6137856 / temp;
                           temp = 276 - temp;
                           }
                        else
                           {
                           if ( temp < 65536 )
                              {
                              temp += 99058;
                              temp = 49086464 / temp;
                              temp = 553 - temp;
                              }
                           else
                              {
                              if ( temp < 262144 )
                                 {
                                 temp += 396700;
                                 temp = 392822784 / temp;
                                 temp = 1106 - temp;
                                 }
                              else
                                 {
                                 if ( temp < 1048576 )
                                    {
                                    temp >>= 2;    //temp / 4;
                                    temp += 396700;
                                    temp = 392822784 / temp;
                                    temp = 1106 - temp;
                                    temp <<= 1;      //temp * 2;
                                    }
                                 else
                                    {
                                    if ( temp < 4194304 )
                                       {
                                       temp >>= 4;    //temp / 16;
                                       temp += 396700;
                                       temp = 392822784 / temp;
                                       temp = 1106 - temp;
                                       temp <<= 2;       //temp * 4;
                                       }
                                    else
                                       {
                                       if ( temp < 16777216 )
                                          {
                                          temp >>= 6;    //temp / 64;
                                          temp += 396700;
                                          temp = 392822784 / temp;
                                          temp = 1106 - temp;
                                          temp <<= 3;     //temp * 8;
                                          }
                                       else
                                          {
                                          if ( temp < 67108864 )
                                             {
                                             temp >>= 8;      //temp / 256;
                                             temp += 396700;
                                             temp = 392822784 / temp;
                                             temp = 1106 - temp;
                                             temp <<= 4;     //temp * 16;
                                             }
                                          else
                                             {
                                             if ( temp < 268435456 )
                                                {
                                                temp >>= 10;     //temp / 1024;
                                                temp += 396700;
                                                temp = 392822784 / temp;
                                                temp = 1106 - temp;
                                                temp <<= 5;   //temp * 32;
                                                }
                                             else
                                                {
                                                if ( temp < 1073741824 )
                                                   {
                                                   temp >>= 12;     //temp / 4096;
                                                   temp += 396700;
                                                   temp = 392822784 / temp;
                                                   temp = 1106 - temp;
                                                   temp <<= 6;     //temp * 64;
                                                   }
                                                else
                                                   {
                                                   temp >>= 14;   // 16384;
                                                   temp += 396700;
                                                   temp = 392822784 / temp;
                                                   temp = 1106 - temp;
                                                   temp <<= 7;     //temp * 128;
                                                   }
                                                }
                                             }
                                          }
                                       }
                                    }
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }

   
   return temp;
   }