用于计算平方根的递归算法

时间:2013-11-12 08:09:21

标签: c

我有一个代码可以通过以下方式计算数字的平方根:

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);
}

我不知道为什么要使用n*10000 - i*i。有人可以解释一下这段代码吗?

5 个答案:

答案 0 :(得分:8)

让我们考虑示例n=100。对于第一批递归,我们有i=1,2,3,...。因此,对于这些调用,我们有n*10000 - i*i >= 0。然后在某个时刻我们i=999并观察n*10000 - 999*999 >= 0。下一个递归步骤为i=1000,我们看到n*10000 - 1000*1000 <= 0,因此我们打印(double)i / 100,然后只有10。如您所见,结果只是n=100的sqare根。

一般来说,满足i/100的最小数字n*10000 - i*i <= 0是&#34;非常接近&#34;到n的sqare根,因为以下内容:

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

我们有:

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

因此,我们正在寻找大于或等于i/100的最小数字sqrt(n),并将此数字用作sqrt(n)的近似值。

答案 1 :(得分:3)

您使用ni调用该函数, 现在,只要i*i小于n * 10000,就会增加i

如果您的i * i大于n * 10000,则打印i / 100

例如:用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

编辑:另一个例子,你寻找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

编辑:你可能会问为什么n * 10000,因为计算错误会变小,例如:如果你在8个例子的sqrt中使用n * 100和i / 10你就得到了

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

答案 2 :(得分:1)

这只是为了增加一些精确度。

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);
}

此代码仅适用于完美的方形数字。

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);
}

此代码适用于所有数字,但在浮点后只给出一位数的结果。

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);
}

这是您的代码,它在浮点后提供2位数的精度。 因此,根据您的要求,(n * 10000) - (i * i)是必要的。 如果你想找到唯一完美的,你也可以使用第一个代码。

答案 3 :(得分:0)

考虑这个功能:

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

这个函数将递归循环遍历i直到i ^ 2&gt; = n,它基本上与没有递归的情况相同:

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

现在10000的技巧只是添加一些由大整数模拟的精度(注​​意它可能会更快地溢出一个int) - 你计算sqrt(100 * 100 * n),即100 * sqrt(n ),因此您将结果除以100.这使您可以获得2位数的精度。

答案 4 :(得分:0)

因为它会将结果舍入为两位小数。

例如,

 n = 10,结果为3.17。

如果你想将结果舍入为3位小数,你可以写:

如果((N * 1000000) - (I * I)&LT; = 0)     的printf( “%F”,(双)I / 1000);