Newton-Raphson在C ++中使用递归

时间:2016-10-30 21:28:09

标签: c++ recursion

我编写了以下代码来使用牛顿方法计算平方根,但每次运行它时它都会溢出。我自己尝试过检查,但没有发现任何错误。你能帮助我吗?

double root(double n,double init){
    if(fabs(init*init-n)<=0.00001){
        return init;
    }else{
        init=(init*init-n)/2*init;
        return root(n,init);
   }
}
int main()
{
    double a;
    cout<<"Enter any number to get its square root: ";
    cin>>a;
    cout<<"Square Root of "<<a<<" is: "<<root(a,2);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

所以你的问题是双重的。首先,你的牛顿方法稍微偏离(这是一个更大的问题)。其次,你实现它的方式导致溢出。

问题1(更大的问题):

其他答案似乎忽略了这一点,即使这是一个更大的问题。计算机可以处理小数字的平方溢出,例如计算9的平方根时,但是你的方法甚至对它们都不起作用。这是因为,正如我在评论中提到的,你的牛顿方法略有偏差。

你应该在这一行中使用加号而不是减号(尝试重新发现以了解原因):

init=(init*init+n)/(2*init);

推导:

x_{k+1} = x_k - f(x_k)/f'(x_k)
        = x_k - ((x_k)^2 - n)/(2x_k)
        = x_k - 1/2*x_k + n/(2x_k)  // note the + here
        = 0.5*x_k + 0.5*n/x_k
        = 0.5*(x_k + n/x_k)

其中x_k是您的init变量。

问题2:

执行init*init会导致数字过快增长并溢出(更大的数字会出现更多错误)。您可以将其代数重写为:

init=0.5*(init + n/init);

把它们放在一起:

#include <iostream>
#include <cmath>
using namespace std;
double root(double n,double init){
    if(fabs(init*init-n)<=0.00001){
        return init;
    }else{
        init=0.5*(init + n/init);
        return root(n,init);
   }
}
int main()
{
    double a;
    cout<<"Enter any number to get its square root: ";
    cin>>a;
    cout<<"Square Root of "<<a<<" is: "<<root(a,2);
    return 0;
}

答案 1 :(得分:0)

您正在使用递归,这可能会溢出您的堆栈。例如,我试图输入9999并且你的程序永远挂起(因为n没有减少)。

另一个问题是double * double可能溢出。

正确(高效,简洁和迭代)的版本是:

double root(double n){ // you dont need the second parameter
    double val = n; // initial guess
    for(;;) {
        double last = val;
        val = (val + n / val) * 0.5; // iterative
        if (abs(val - last) < 1e-9) break;  // error small enough
    }
    return val;
}

如果你坚持递归,这里有一个更简洁的递归实现:

double root(double n, double last){
    if (abs(last * last - n) < 1e-9) { // good guess
            return last;
    }
    return root(n, 0.5 * (last + n / last)); // recursive call
}

另请see "Newton Iterative Sqrt Method"了解更多信息。