I have written a program that computes an estimated value of sqrt(x):
Explanation of the code below
I'm trying to find the nearest number (S) to (x) which can be represented as S=sqrt*sqrt, keep looping until fabs(_sqrt - sqrt) >= 1e-8
is not correct that means that sqrt and _sqrt are very close.
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
double val, min, max;
double sqrt;
double S, _sqrt;
int cnt = 0;
// enter an argument,
if (argc < 2) {
printf ("Usage: sqrt < number >\n");
return 1;
}
val = fabs (atof (argv[1]));
min = 0;//minimum
max = sqrt = val;//maximum
_sqrt = 1;
//1e-8 = 10^(-8) = 0.00000001
while (fabs(_sqrt - sqrt) >= 1e-8) {
_sqrt = sqrt;//keep the old sqrt
sqrt = (max + min) / 2;
S = sqrt * sqrt;
printf("test n(%d)\tsqrt(%lf) = %.6lf\n",++cnt,val, sqrt);
if (S>val){
max = sqrt;//setting max to the current sqrt
} else{
min = sqrt;//setting min to the current sqrt
}//end else
}//end while
puts("");
puts("\t====================================================");
printf ("\tfinal value.\tsqrt(%lf) = %.6lf\n", val, sqrt);
puts("\t====================================================");
return 0;
}//end main()
the output
[ar.lnx@host square-root] $ ./sqrt 2
test n(1) sqrt(2.000000) = 1.000000
test n(2) sqrt(2.000000) = 1.500000
test n(3) sqrt(2.000000) = 1.250000
test n(4) sqrt(2.000000) = 1.375000
test n(5) sqrt(2.000000) = 1.437500
test n(6) sqrt(2.000000) = 1.406250
test n(7) sqrt(2.000000) = 1.421875
test n(8) sqrt(2.000000) = 1.414062
test n(9) sqrt(2.000000) = 1.417969
test n(10) sqrt(2.000000) = 1.416016
test n(11) sqrt(2.000000) = 1.415039
test n(12) sqrt(2.000000) = 1.414551
test n(13) sqrt(2.000000) = 1.414307
test n(14) sqrt(2.000000) = 1.414185
test n(15) sqrt(2.000000) = 1.414246
test n(16) sqrt(2.000000) = 1.414215
test n(17) sqrt(2.000000) = 1.414200
test n(18) sqrt(2.000000) = 1.414207
test n(19) sqrt(2.000000) = 1.414211
test n(20) sqrt(2.000000) = 1.414213
test n(21) sqrt(2.000000) = 1.414214
test n(22) sqrt(2.000000) = 1.414214
test n(23) sqrt(2.000000) = 1.414213
test n(24) sqrt(2.000000) = 1.414214
test n(25) sqrt(2.000000) = 1.414214
test n(26) sqrt(2.000000) = 1.414214
test n(27) sqrt(2.000000) = 1.414214
test n(28) sqrt(2.000000) = 1.414214
====================================================
final value. sqrt(2.000000) = 1.414214
====================================================
but it works only for every x>=1, if i want to calculate the sqrt of 0.5 or 0.254 or 0.1... it not works!
[ar.lnx@host square-root] $ ./sqrt1 0.5
test n(1) sqrt(0.500000) = 0.250000
test n(2) sqrt(0.500000) = 0.375000
test n(3) sqrt(0.500000) = 0.437500
test n(4) sqrt(0.500000) = 0.468750
test n(5) sqrt(0.500000) = 0.484375
test n(6) sqrt(0.500000) = 0.492188
test n(7) sqrt(0.500000) = 0.496094
test n(8) sqrt(0.500000) = 0.498047
test n(9) sqrt(0.500000) = 0.499023
test n(10) sqrt(0.500000) = 0.499512
test n(11) sqrt(0.500000) = 0.499756
test n(12) sqrt(0.500000) = 0.499878
test n(13) sqrt(0.500000) = 0.499939
test n(14) sqrt(0.500000) = 0.499969
test n(15) sqrt(0.500000) = 0.499985
test n(16) sqrt(0.500000) = 0.499992
test n(17) sqrt(0.500000) = 0.499996
test n(18) sqrt(0.500000) = 0.499998
test n(19) sqrt(0.500000) = 0.499999
test n(20) sqrt(0.500000) = 0.500000
test n(21) sqrt(0.500000) = 0.500000
test n(22) sqrt(0.500000) = 0.500000
test n(23) sqrt(0.500000) = 0.500000
test n(24) sqrt(0.500000) = 0.500000
test n(25) sqrt(0.500000) = 0.500000
test n(26) sqrt(0.500000) = 0.500000
====================================================
final value. sqrt(0.500000) = 0.500000
====================================================
Can someone help me understand what the problem is and how to fix it?
The reason is that your conversion logic only works if val > 1
Note the way you test the sqrt(.5)
Since when val == 0.5
you get S = val * val
which is 0.25
. This resets min
to 0.25
Since sqrt = (max + min) / 2;
and the initial max
is val
(0.5) you can never get past 0.5
.
You will have to determine that since your initial val
is less than 1, you want your initial max
to be 1 so that your average is val < sqrt < 1
If you do this, then you should converge on the correct value.
I do not have access to a C compiler at this time. However, by initial inspection the first average is 1.5/2 == .75
which resets max. The new average is 1.25/2 == .625
which resets min You should then continue until you converge on the correct value.
FYI you can also use the contents of the while loop as a different function in order to teach yourself recursion. That is, instead of looping through the while, if S > lim {call the new estimate function} once it falls through the recursion, it will pass the final estimate back up to the initial calling function.