Jump to content
Hiker

Errors In Square Root Function?

Recommended Posts

Hi

 

I found something I see as an arithmetic error in the sqrt() function.

Initially, I chose to use the sqrt1() function, when it immediately seemed to work as expected.

 

But to be sure that there were errors, I tried to write a small test routine:

 

	unsigned int Cntr, Square, Root, Root1;

//	DebugPrint("Cntr, Square, Root, Root1");

for(Cntr = 0; Cntr <= 255; Cntr++)
{
	Square = Cntr * Cntr;
	Root   = sqrt(Square);
	Root1  = sqrt1(Square);

	if((Root != Cntr) || (Root1 != Cntr))
//			DebugPrint("%4u,%7u,%5u,%5u", Cntr, Square, Root, Root1);
}

And the result shows that, on my PC, there are problems with the sqrt() routine, and sqrt1() gives true result by the square numbers:

 

  Cntr, Square, Root, Root1
17,	289,   16,   17
33,   1089,   32,   33
34,   1156,   32,   34
35,   1225,   32,   35
65,   4225,   64,   65
66,   4356,   64,   66
67,   4489,   64,   67
68,   4624,   64,   68
69,   4761,   64,   69
70,   4900,   64,   70
71,   5041,   64,   71
97,   9409,   96,   97
  129,  16641,  128,  129
  130,  16900,  128,  130
  131,  17161,  128,  131
  132,  17424,  128,  132
  133,  17689,  128,  133
  134,  17956,  128,  134
  135,  18225,  128,  135
  136,  18496,  128,  136
  137,  18769,  128,  137
  138,  19044,  128,  138
  139,  19321,  128,  139
  140,  19600,  128,  140
  141,  19881,  128,  141
  142,  20164,  128,  142
  143,  20449,  128,  143
  193,  37249,  192,  193
  194,  37636,  192,  194

I have not tried to find out how the rounding is, at the intermediate values between the square numbers.

 

My setup is:

Win XP, En, SP3

MPLAB v8.40

BoostC v6.97

Target: PIC18F67J10

Share this post


Link to post
Share on other sites

Hiker,

 

Hi

 

I found something I see as an arithmetic error in the sqrt() function.

...

This is indeed a problem.

I'm not sure how the error is creeping in.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Here is a simple funtion:

 

unsigned char sqrtz(unsigned short val)
{
unsigned short res, one;

res = 0;

one = (65535 >> 2) + 1;
while (one > val) one >>= 2;

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

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

Hello again

 

Now I finally have time to test whether my problem is solved with BoostC v7.03

 

At the exact square numbers both sqrt() and sqrt1() gives the correct result.

 

But the values between the squares numbers, it appears that sqrt() always rounds down to nearest integer and sqrt1() rounds to the nearest integer.

 

The most accurate result is still sqrt1(), except when you reach over 65280 (255.5^2) where the return value is rounded up to 256 and returned as a zero.

Share this post


Link to post
Share on other sites

Your content will need to be approved by a moderator

Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×