我有一个代码可以通过以下方式计算数字的平方根:
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
。有人可以解释一下这段代码吗?
答案 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)
您使用n
和i
调用该函数,
现在,只要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);