Hiker 0 Report post Posted February 28, 2011 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 Quote Share this post Link to post Share on other sites

Dave 0 Report post Posted March 22, 2011 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 Quote Share this post Link to post Share on other sites

Reynard 0 Report post Posted March 22, 2011 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 Quote Share this post Link to post Share on other sites

Hiker 0 Report post Posted June 14, 2011 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. Quote Share this post Link to post Share on other sites