View Single Post
  #8   Spotlight this post!  
Unread 15-02-2004, 11:23
Paul Paul is offline
lacks sanity
FRC #0316 (LuNaTeCs)
Team Role: College Student
 
Join Date: Jan 2003
Rookie Year: 2002
Location: Salem,NJ
Posts: 14
Paul is an unknown quantity at this point
Send a message via AIM to Paul
Talking Re: Square Root Function not working

Quote:
Originally Posted by kiracofe8
Why this goes over has already been answered, but I should also point out that this algorithm will be incredibly slow, and not particularly accurate. Two things:

First off, it is a cardinal sin to have a floating point value as a loop index. The problem is that floating point numbers always have some round off error. And, each time you add, the round off error increases. So, for example, if tar = 1, and accr = 0.1, after 10 iterations, you may get i = 0.9999999 or you may get i = 1.0000001. If you get the former, you'll end up with the square of 1 = 1.1 b/c you'll go one step too far. If you get the later, you'll get the right answer. But there is no way to know which you'll get ahead of time.

The problem of floating point loop indexes can cause such subtle bugs that some languages do not allow it at all (e.g. recent versions of FORTRAN). The following is the recommended replacement:

Code:
float sqrt(unsigned int tar, float accr)
{
    int i;
    float j;

    j = 0;

    for (i=0;j<tar;i++)
    {
        j = i * accr;
        if (j*j >= tar)
            return j;
    }
    return -1; //signal an error.  should never happen, but it is bad form to
                  //simply not return any value.    
}
Secondly: the algorithm itself converges slowly. E.g. if you try to take the square root of, say, 100 with accr = 0.1, it will take a LONG time (1000 iterations) to get a correct answer. Try a different method. The most common method to numerically compute square roots is called Newton's method. Do a search on google for "Newton's method square root" and you should find some good example code. Newton's method will converge to a reasonable value after only a few iterations.
I've used Newton's system of finding square roots, and it is pretty fast. Take a look at this code, it only works for ints but it should be good enough for what you need. It takes a a number of interations equal to the square root. For instance, to get the sqr of 16 it would take 4 interations, 100 would be 10 and so on and so forth. See how you like it.

inline int sroot(int n)
{
int c = 0; int a = 1;
do {n -= a; a += 2; ++c;}
while (n > 0);
return c;
}

Last edited by Paul : 15-02-2004 at 11:31.