我无法计算 0<= number <1 的平方
I can't compute the sqrt of a 0<= number <1
我编写了一个程序来计算 sqrt(x) 的估计值:
下面代码的解释
我正在尝试找到最接近 (x) 的数字 (S),它可以表示为 S=sqrt*sqrt,继续循环直到 fabs(_sqrt - sqrt) >= 1e-8
不正确,这意味着 sqrt 和 _sqrt 非常接近。
#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()
输出
[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
====================================================
但它只适用于每个 x>=1,如果我想计算 0.5 或 0.254 或 0.1 的平方...它不起作用!
[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
====================================================
有人可以帮助我了解问题所在以及解决方法吗?
问题是您正在将 max
初始化为 val
。对于小于 1 的数字,平方根将 大于 ,而不是小于该数字。例如,对于 0.5,平方根是 0.707...如果 val
小于 1,一个简单的解决方法是将 max
初始化为 1。
问题是您的 max
值必须大于或等于预期结果。如果您的输入小于1.0
,则结果大于输入且小于1.0
。您的 max
值必须至少为 1.0
。像这样调整您的代码。
#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]));
if ( val < 1.0 )
{
min = val;
max = sqrt = 1.0; // if val < 1.0 result is greater than val but less than 1.0
}
else
{
min = 0; //minimum
max = sqrt = val; //maximum
}
do
{
_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
}
while ( fabs(_sqrt - sqrt) >= 1e-8); //1e-8 = 10^(-8) = 0.00000001
puts("");
puts("\t====================================================");
printf ("\tfinal value.\tsqrt(%lf) = %.6lf\n", val, sqrt);
puts("\t====================================================");
return 0;
}
原因是您的转换逻辑仅在 val > 1
时有效
注意你测试 sqrt(.5)
的方式,因为当 val == 0.5
你得到 S = val * val
即 0.25
。这会将 min
重置为 0.25
因为 sqrt = (max + min) / 2;
并且初始 max
是 val
(0.5) 你永远无法超越 0.5
.
您必须确定,由于您的初始 val
小于 1,因此您希望初始 max
为 1,以便您的平均值为 val < sqrt < 1
如果你这样做,那么你应该收敛到正确的值。
我现在无法使用 C 编译器。但是,通过初步检查,第一个平均值是 1.5/2 == .75
,它会重置最大值。新的平均值是 1.25/2 == .625
,它会重置 min 你应该继续,直到你收敛到正确的值。
仅供参考,您还可以将 while 循环的内容用作不同的函数,以便自学递归。也就是说,如果 S > lim {调用新的估计函数},而不是通过 while 循环,一旦它通过递归,它会将最终估计传递回初始调用函数。
我编写了一个程序来计算 sqrt(x) 的估计值:
下面代码的解释
我正在尝试找到最接近 (x) 的数字 (S),它可以表示为 S=sqrt*sqrt,继续循环直到 fabs(_sqrt - sqrt) >= 1e-8
不正确,这意味着 sqrt 和 _sqrt 非常接近。
#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()
输出
[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
====================================================
但它只适用于每个 x>=1,如果我想计算 0.5 或 0.254 或 0.1 的平方...它不起作用!
[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
====================================================
有人可以帮助我了解问题所在以及解决方法吗?
问题是您正在将 max
初始化为 val
。对于小于 1 的数字,平方根将 大于 ,而不是小于该数字。例如,对于 0.5,平方根是 0.707...如果 val
小于 1,一个简单的解决方法是将 max
初始化为 1。
问题是您的 max
值必须大于或等于预期结果。如果您的输入小于1.0
,则结果大于输入且小于1.0
。您的 max
值必须至少为 1.0
。像这样调整您的代码。
#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]));
if ( val < 1.0 )
{
min = val;
max = sqrt = 1.0; // if val < 1.0 result is greater than val but less than 1.0
}
else
{
min = 0; //minimum
max = sqrt = val; //maximum
}
do
{
_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
}
while ( fabs(_sqrt - sqrt) >= 1e-8); //1e-8 = 10^(-8) = 0.00000001
puts("");
puts("\t====================================================");
printf ("\tfinal value.\tsqrt(%lf) = %.6lf\n", val, sqrt);
puts("\t====================================================");
return 0;
}
原因是您的转换逻辑仅在 val > 1
注意你测试 sqrt(.5)
的方式,因为当 val == 0.5
你得到 S = val * val
即 0.25
。这会将 min
重置为 0.25
因为 sqrt = (max + min) / 2;
并且初始 max
是 val
(0.5) 你永远无法超越 0.5
.
您必须确定,由于您的初始 val
小于 1,因此您希望初始 max
为 1,以便您的平均值为 val < sqrt < 1
如果你这样做,那么你应该收敛到正确的值。
我现在无法使用 C 编译器。但是,通过初步检查,第一个平均值是 1.5/2 == .75
,它会重置最大值。新的平均值是 1.25/2 == .625
,它会重置 min 你应该继续,直到你收敛到正确的值。
仅供参考,您还可以将 while 循环的内容用作不同的函数,以便自学递归。也就是说,如果 S > lim {调用新的估计函数},而不是通过 while 循环,一旦它通过递归,它会将最终估计传递回初始调用函数。