6

I have a code that calculates the square root of a number the following way:

void f1(int,int);

int main(){
    int i=1;
    int n;
    scanf("%d",&n);
    f1(n,i);
    getch();
    return 0;
}

void f1(int n,int i){
    if((n*10000)-(i*i)<=0)
        printf("%f",(double)i/100);
    else
        f1(n,i+1);
}

I don't know why using n*10000 - i*i. Can someone explain this code please?

1
  • 1
    Please, indent your code Commented Nov 12, 2013 at 8:10

5 Answers 5

8

Lets consider the example n=100. For the first bunch of recursions, we have i=1,2,3,.... Thus, for these calls, we have n*10000 - i*i >= 0. Then at some point we have i=999 and observe that n*10000 - 999*999 >= 0. The next recursive step has i=1000 and we see that n*10000 - 1000*1000 <= 0, so we print (double)i / 100, which is then just 10. As you can see, the result is just the sqare root of n=100.

In general, the smallest number i/100 satisfying n*10000 - i*i <= 0 is "quite close" to the sqare root of n, because of the following:

sqrt(n*10000) = sqrt(n)*sqrt(10000) = sqrt(n)*100

And we have:

n*10000 - i*i <= 0            | +i*i
      n*10000 <= i*i          | sqrt both sides
  sqrt(n)*100 <= i            | /100
      sqrt(n) <= i/100

Thus, we are looking for the smallest number i/100 that is greater or equal to sqrt(n) and use this number as an approximation for sqrt(n).

Sign up to request clarification or add additional context in comments.

2 Comments

@zubergu Doesn't it increase precision? If you worked without the multiplication, you obtain a plain integer i (in the mathematical sense), while - with multiplication - you (basically) can get a decimal number with two decimal places.
@zubergu you could use n*100 and i/10 but its less accurate, so the error gets bigger
3

you call the function with n and i, now as long as i*i is smaller than n * 10000 you increase your i.

if your i*i is bigger than n * 10000 you print i / 100

eg: you call function with f1(1,1):

 1*10000 >= 1*1 --> f1(1,2);
 1*10000 >= 2*2 --> f1(1,3);
 1*10000 >= 3*3 --> f1(1,4);
 ....
 1*10000 >= 99*99 ->f1(1,100);
 1*10000 <= 100*100 --> printf("%f",i/100.0); which gives: 1

EDIT: another example, you look for the sqare root of 8: f1(8,1);

 8*10000 >= 1*1 --> f1(8,2);
 8*10000 >= 2*2 --> f1(8,3);
 1*10000 >= 3*3 --> f1(8,4);
 ....
 8*10000 >= 282*282 ->f1(8,283);
 8*10000 <= 283*283 --> printf("%f",i/100.0); which gives: 2.83

 and 2.83 * 2.83 = 8.0089

EDIT: you may ask why n*10000, its because the calculation error gets smaller, eg: if you use n*100 and i/10 in the sqrt of 8 example you get

8*100 <= 29*29 --> 2.9
2.9 * 2.9 = 8.41 which is not good as 2.83 in the other example

Comments

1

That is just to add some precision.

void f1(int n,int i){
    printf("value of i is=%d \n",i);
    if(n-i*i<=0)
        printf("%f",i);
    else
        f1(n,i+1);
}

this code will work for only perfect square numbers.

void f1(int n,int i){
    printf("value of i is=%d \n",i);
    if((n*100)-(i*i)<=0)
        printf("%f",(double)i/10);
    else
        f1(n,i+1);
}

this code will work for all numbers but will give result for just one digit after floating point.

void f1(int n,int i){
    printf("value of i is=%d \n",i);
    if((n*10000)-(i*i)<=0)
        printf("%f",(double)i/100);
    else
        f1(n,i+1);
}

this is your code which gives 2 digit point precision after floating point. so that (n*10000)-(i*i) is necessary as per your requirement. if you want to find for only perfect you can use first code too.

Comments

0

Consider this function:

void f1(int n,int i){
    if((n)-(i*i)<=0)
        printf("%f",i);
    else
        f1(n,i+1);
}

This function would recursively loop over i until i^2 >=n, it's basically the same as doing this without recursion:

void f1(int n,int i){
    int i = 1;
    while (i*i < n)
        ++i;
    printf("%f",i);
}

Now the trick with the 10000 is just to add some precision emulated by large integers (note that it might overflow an int faster like that) - you calculate sqrt(100*100*n), which is 100*sqrt(n), so you divide the result by 100. This allows you to get a 2 digit precision.

Comments

0

because it will get the result rounded to two decimals.

for example, n=10 the result is 3.17.

and if you want to get result rounded to 3 decimals, you can write:

if((n*1000000)-(i*i)<=0) printf("%f",(double)i/1000);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.