繁体   English   中英

在 C++ 中获得平方根的巴比伦算法中的无限循环

[英]Getting an infinite loop in Babylonian Algorithm for square roots in C++

我在互联网上彻底搜索了这个主题,这些线程要么死了,要么使用了与我书中描述的方法不同的方法。

例如, http://www.geeksforgeeks.org/square-root-of-a-perfect-square/ 这对我不起作用,因为我的算法需要循环直到达到最后一个“猜测”的 1%。

这是来自文本的问题。

计算数字 n 的平方根的巴比伦算法如下:

  1. 猜测数字(您可以选择 n/2 作为您的初始猜测)。
  2. 计算 r = n / 猜测
  3. 设置猜测=(猜测+ r)/ 2
  4. 返回到第 2 步进行尽可能多的迭代。 重复步骤 2 和 3 的次数越多,猜测值就越接近 n 的平方根。

编写一个程序,输入 n 的整数,迭代巴比伦算法,直到猜测值在前一次猜测值的 1% 以内,然后将答案输出为双精度值。

我编写了以下代码:

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

int main()
{
int  n;
double r, guess(4), lastGuess;

cout << "Enter a number to find the square root of: ";
cin >> n;

do
{

    r = n / guess;
    lastGuess = guess;
    guess = ( guess + r ) / 2;

//  cout <<"Guess: " << guess << endl;
//  cout <<"Last Guess: " << lastGuess << endl;

    cout << "Guess : " << guess  << endl;
    cout << "Last Guess 1% = " << lastGuess + ( lastGuess * 0.01 ) << endl;
    cout << "r = " << r << endl;

} while( guess >= lastGuess * 0.01 );
cout << r;

return 0;
}

程序计算 r 的正确答案,但尽管猜测加到 lastGuess 大于 1%,但循环并未终止。

当输入 144 作为 n 时,该程序产生以下输出。

....
r = 12
Guess : 12
Last Guess 1% = 12.12
r = 12
Guess : 12
Last Guess 1% = 12.12
r = 12
Guess : 12
Last Guess 1% = 12.12
r = 12
Guess : 12
Last Guess 1% = 12.12
....

根 (r) 是正确的 (12)。 猜测小于 lastGuess (12 < 12.12),这应该返回一个错误的条件,对吗?。 为什么循环没有结束?

如果你想增加 1%,你需要乘以 1.01,而不是 0.01。

while( guess >= lastGuess * 1.01 );

顺便说一句,当guess 增长超过1% 时,它会进行迭代。 您还应该考虑到相反的情况,即它可能缩小了 1% 以上。 近似值可以从任一方向接近答案。 (它将从右侧接近正根,从左侧接近负根。)

在打印您正在使用的lastGuess 时

 lastGuess + ( lastGuess * 0.01 )

但是在检查您正在使用的循环条件时

lastGuess*0.01

因此,在循环条件中使用您用于打印lastGuess值的相同等式。

要正确退出循环,请使用与此类似的方法。

void f(int N)
{
    double x = N / 4;
    double prev = 0.0f;

    while(1)
    {
        x = 0.5 * (x + N / x);
        if (prev == x)
            break;

        prev = x;
        printf("val: %f\n", x);
    }

    printf("SQRT(%d) = %f\n", N, x);
}

我在我的书中遇到了同样的问题。 这就是我写的,它完美无缺。

#include <iostream>
using namespace std;
int main()
{
    double guess, root, previousGuess;
    int number;
    cout << "Enter a number to find the Babylonian square root.\n";
    cin >> number;
    cout << "You want to find the square root of " << number << ".\n";
    cout << "Enter a guess for the square root.\n";
    cin >> guess;

    do
    {
        root = number / guess;
        previousGuess = guess;
        guess = (guess + root ) / 2;

    } while(guess < 0.99*previousGuess || guess > 1.01*previousGuess);

    cout << "The answer is " << guess << ".\n";
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM