C ++查找没有sqrt函数循环故障的平方根

时间:2017-02-16 00:01:38

标签: c++ loops square-root

所以我把它作为家庭作业。我知道有很多方法可以使这段代码更加高效和准确,但这是我教授希望它完成的方式。

我遇到循环问题。当我要求67的平方根时,它确实找到了它,但它循环了正确的答案3次。

Enter a value to be square rooted: 
67
33.5
guess = 17.75
guess = 10.7623
guess = 8.49387
guess = 8.19096
guess = 8.18535
guess = 8.18535
guess = 8.18535
The program took 7 guess to find an estimation. 

当我试图找到5的平方根时,它会找到它,但会继续无限循环

using namespace std;

int main()
{
double guess2;
double squarenumber;
double guess1;
int numofguess = 0;

cout << "Enter a value to be square rooted: " << endl;
cin >> squarenumber;
guess1 = squarenumber/2;
cout << guess1 << endl;

do 
{

guess2 = (guess1 - (((guess1 * guess1) - squarenumber)/(2* guess1)));
guess1 = guess2;

cout << "guess = " << guess2 << endl;

numofguess = numofguess + 1;

} while ((guess2 * guess2) > squarenumber);

cout<< "The program took "<< numofguess <<" guess to find an estimation.";

return 0;
}

2 个答案:

答案 0 :(得分:1)

我认为你缺少的是正确的退出条件。 您的代码将被无限循环地写入,直到猜测为#34;完美&#34;。 您应该有退出条件检查当前猜测是否与之前的猜测相同,这显然意味着您不会做得更好。 以下是基于您的代码的建议:

using namespace std;

int main()
{
double guess2;
double squarenumber;
double guess1;
int numofguess = 0;

cout << "Enter a value to be square rooted: " << endl;
cin >> squarenumber;
guess2 = guess1 = squarenumber/2;
cout << guess1 << endl;

const double epsilon = squarenumber * 1E-6;
do 
{
 guess1 = guess2;
guess2 = (guess1 - (((guess1 * guess1) - squarenumber)/(2* guess1)));


cout << "guess = " << guess2 << endl;

numofguess = numofguess + 1;

} while ((guess2 * guess2) > squarenumber && fabs(guess2-guess1) > epsilon);

cout<< "The program took "<< numofguess <<" guess to find an estimation.";

return 0;
}

答案 1 :(得分:0)

MickaëlC.Guimarães的回答基本上是正确的,检查一个episolon值(与正确答案和你的答案的绝对差异)。但是应该完全删除“(guess2 * guess2)&gt; squarenumber”。那是因为理论上这个价值可能会超调并且太低。如果该值太低,该算法实际上会上升。例如如果你想要SQRT(25)并且你的“guess1”预测在2处太低,则guess2将等于

(2 - (((2 * 2) - 25)/(2* 2))) = 7.25;

在下一次迭代中,然后下降到6.725624,所以朝着正确的方向前进。低值实际上得到提升并最终接近目标。如果值低于真正的SQRT,那么你可能会得到“误报”,其中过低的值被认为是足够准确的。

系统被“卡住”的时间基本上就像故事Acchiles和Tortoise。在每个步骤中,系统将剩余距离除以一定量,但是每一步的变化都较小,理论上可能永远不会收敛到精确值,因此您可以决定您想要多少准确度,以便完成一段时间。

此外,系统似乎采取了太多步骤来收敛的问题是因为浮点数以更高的精度存储,但是cout的显示精度有限。您可以通过在打印命令之前将设置值发送到cout来控制它:

std::cout << std::fixed; // force all values to show to the same decimals
std::cout << std::setprecision(6); // set how many places to show

这些代码可以在打印值之前在一个命令中流式传输到cout:

std::cout << std::fixed << std::setprecision(6) << "guess = " << guess2 << endl;