|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
||||
|
||||
|
Square Root Function not working
Why isn't this working? I always get a value that's too high. 4 would give me the correct value, but 9 up always goes over. It's kind of weird too, every perfect square makes it go over a little less, you can check it out and see what I mean.
Code:
float sqrt(unsigned int tar, float accr)
{
float i;
for (i=0.0f;i<tar;i+=accr)
{
if (i*i >= tar)
return i;
}
}
|
|
#2
|
|||
|
|||
|
http://www.chiefdelphi.com/forums/sh...618#post221618
I responded to your origonal post. See if it helps you out any. ![]() |
|
#3
|
|||
|
|||
|
Re: Square Root Function not working
This code is based on an algorithm I found on Microchip's web site. Its for 32 bit integers, but can be adapted for 24 and 16 bit ints by changing the mask and result values.
Code:
typedef unsigned long uint32;
uint32 sqrt32(uint32 x)
{
uint32 mask = 0x1000;
uint32 result = 0x800;
while (mask > 0)
{
if ((result * result) > x)
{
result &= (~mask);
}
mask >>= 1;
result |= mask;
}
return result;
}
|
|
#4
|
||||||
|
||||||
|
Re: Square Root Function not working
Quote:
-Chris |
|
#5
|
||||||
|
||||||
|
Re: Square Root Function not working
Quote:
It is always high due to the >= that you have in the 'if' statement. It won't return a value until it becomes equal or GREATER THAN your value. The odds of it being equal are quite low. Therefore, you're always going to get something that is higher. In fact, it is IMPOSSIBLE to get a value that is lower than the actual square root. I see two ways to increase your accuracy (I could probably come up with more, but I just woke up). The first is to make 'accr' smaller. This will give you more accuracy. However, this will also result in slower code. Here is another way the should give you decent accuracy without much more computation: linearly interpolate between the two points surrounding the square root. Here is an example: Code:
float sqrt(unsigned int tar, float accr)
{
float i;
float i_prev;
for (i=0.0f;i<tar;i+=accr)
{
if (i*i >= tar)
break;
i_prev = i;
}
// return a linearly interpolated value
return (tar*tar - i_prev*i_prev)/(i*i - i_prev*i_prev) *
(i - i_prev) + i_prev;
}
If you don't want to get that complicated, just average the two values surrounding your target: Code:
float sqrt(unsigned int tar, float accr)
{
float i;
float i_prev;
for (i=0.0f;i<tar;i+=accr)
{
if (i*i >= tar)
break;
i_prev = i;
}
// return the average of the point before and the point after the sqrt
return (i + i_prev)/2;
}
|
|
#6
|
|||
|
|||
|
Re: Square Root Function not working
Quote:
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.
}
|
|
#7
|
|||
|
|||
|
Quote:
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. |
|
#8
|
||||
|
||||
|
Re: Square Root Function not working
Quote:
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Mulit-postioning with pnuematics this year? | KenWittlief | Pneumatics | 101 | 01-02-2005 21:54 |
| Square Root | bludstayne | Programming | 3 | 14-02-2004 14:48 |
| Aspartame | shyra1353 | Chit-Chat | 8 | 20-01-2004 22:41 |
| I'm working :) | Jack | FIRST Scouting Network | 2 | 03-01-2004 01:26 |
| Whose working this summer? | Frank(Aflak) | Chit-Chat | 20 | 28-05-2003 11:35 |