Fast Square root function for integers.

victor_pv
Sat May 02, 2015 2:37 pm
Just wanted to share this square root calculation algorithm that I found a few weeks back:
http://medialab.freaknet.org/martin/src/sqrt/sqrt.c

I compared it to the normal sqrt() function included in the IDE, and to one other routine I found online, and it was about 10x faster than both in average.
It works perfectly good for 32bit integers, returning another integer. Not useful if you need floating point, but if you don’t need more precision than integers (like calculating coordinates in a display, there is no need for decimals), and you calculate a lot of square roots, it may provide some speed improvement to your code.

To compare the speed of each routine I calculated all the square root from 1.000.000 to 1. I could have gone higher, to 4.000.000.000, but it would take a lot of time to calculate it all.
When I have a working mini again, I will test with a few ranges, to see if the speed improvements compared to the standard sqrt function are mostly on certain bit lengths, as the speed depends on the size of the number.

This is the code, but is in that webpage too:
uint16_t asqrt(uint32_t x) {
/* From http://medialab.freaknet.org/martin/src/sqrt/sqrt.c
* Logically, these are unsigned. We need the sign bit to test
* whether (op - res - one) underflowed.
*/
int32_t op, res, one;

op = x;
res = 0;

/* "one" starts at the highest power of four <= than the argument. */

one = 1 << 30; /* second-to-top bit set */
while (one > op) one >>= 2;

while (one != 0) {
if (op >= res + one) {
op = op - (res + one);
res = res + 2 * one;
}
res /= 2;
one /= 4;
}
return (uint16_t) (res);
}


eduardo
Sat Nov 14, 2015 2:02 pm
Hi.
Your algorithm and others are well explained here:
http://www.codecodex.com/wiki/Calculate … quare_root

Please consider that the algorithm was conceived avoiding multiplication. Today even the AVR has a HW MULT. So there are other algorithms that may win. If your code frame is ready for testing you might test this one:

unsigned int sqrt32(unsigned long n)
{
unsigned int c = 0x8000;
unsigned int g = 0x8000;

for(;;) {
if(g*g > n)
{
g ^= c;
}
c >>= 1;
if(c == 0)
{
return g;
}
g |= c;
}
}


jcw
Sat Nov 14, 2015 5:07 pm
Ooh, clever!

RogerClark
Sat Nov 14, 2015 7:45 pm
unsigned int sqrt32(unsigned long n)
{
unsigned int c = 0x8000;
unsigned int g = 0x8000;

for(;;) {

if(g*g > n) {
g ^= c;
}

c >>= 1;

if(c == 0) {
return g;
}

g |= c;

}
}


RJW
Mon Feb 08, 2016 7:31 pm
Thankyou for a useful algorithm. The code worked better for me with g typed as unsigned long

eduardo
Tue Feb 23, 2016 1:13 pm
@RJW.
Glad it helped. I took it from the link above and I did not test it with real code to be true.
Your remark about int or long is interesting. I will have to check it. What means “…worked better..” exactly?
@Roger: Next time I will use proper formatting :D

mrburnette
Tue Feb 23, 2016 2:14 pm
Over the years, I have seen the publication of numerous snippets of code for “fast” calculations of mathematical functions. These algorithms often have bounds where they work and outside the bounds, their accuracy fail. Many were developed and published when computers were far less powerful than today. Many were developed, such as CORDIC, for military and then quickly found their way into consumer uses (CORDIC principles are used in the HP scientific calculators.)

This is where I caution users of such algorithms to build test cases for their data and to carefully and extensively test to ensure the data set is resolved accurately within the operational boundaries of their project. I cannot stress enough that bad results are quickly received when an algorithm go astray.

Ray


zoomx
Wed Feb 24, 2016 3:59 pm
How about Numerical Recipes? Originally written in Fortran now there is also a C version. And a Pascal too.

mrburnette
Wed Feb 24, 2016 4:48 pm
zoomx wrote:How about Numerical Recipes? Originally written in Fortran now there is also a C version. And a Pascal too.

Rick Kimball
Wed Feb 24, 2016 8:13 pm
https://en.wikipedia.org/wiki/Libfixmath

Bunch of routines there that implement fixed point math for you. I’ve compiled that on the msp430 which has very slow floating point routines and got pretty nice results.

-rick


zoomx
Thu Feb 25, 2016 4:37 pm
I read Numerical Recipes when it was only a book and Internet was in a early stage. At that time it was only in Fortran. I don’t remember the Licence at that time.
I don’t like at all the (new?) licence. So, Ray, you’re right!

Leave a Reply

Your email address will not be published. Required fields are marked *