Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I can't compute the sqrt of a 0<= number <1

Tags:

c

sqrt

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?

like image 404
0x0584 Avatar asked Jan 07 '23 17:01

0x0584


2 Answers

The problem is that you're initializing max to val. For numbers less than 1, the square root will be greater than the number, not less. For instance, for 0.5 the square root is 0.707... A simple fix would be to initialize max to 1 if val is less than 1.

like image 62
Tom Karzes Avatar answered Jan 12 '23 15:01

Tom Karzes


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.

like image 34
sabbahillel Avatar answered Jan 12 '23 14:01

sabbahillel