在c++中使用递归的Newton-Raphson
Newton-Raphson using recursion in C++
我编写了下面的代码来使用牛顿方法计算平方根,但是每次运行它都会溢出。我自己试着检查过,但没有发现任何错误。你们能帮帮我吗?
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;
}
所以你的问题是双重的。首先,你的牛顿方法有点偏离(这是一个更大的问题)。其次,你实现它的方式会导致溢出。
第一期(更大的一期):
其他答案似乎忽略了这一点,尽管这是一个更大的问题。计算机可以处理小数字的平方溢出,比如计算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
变量。
做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;
}
标题>您正在使用递归,这可能会溢出堆栈。例如,我试图输入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
}
更多信息请参见"牛顿迭代Sqrt法"
相关文章:
- 通过递归进行因子分解
- 递归函数计算序列中的平方和(并输出过程)
- 使用递归的数组的最小值.这是怎么回事
- 递归列出所有目录中的C++与Python与Ruby的性能
- 递归计数给定目录的文件和所有目录
- 如何在BST的这个简单递归实现中消除警告
- C++:正在检查LinkedList中的回文-递归方法-错误
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 递归无序映射
- TSP递归解的迭代形式
- 如何在Elixir中调用递归函数并行
- 返回递归调用和仅递归调用的区别
- 数组元素打印的递归方法
- 使用递归时获取变量的奇怪值
- 如何在C++中递归地按相反顺序打印集合
- 到连接组件算法的问题(递归)
- 如何使用递归打印修改后的星号三角形图案
- 使用递归模板动态分配的多维数组
- 递归函数有效,但无法记忆
- 在c++中使用递归的Newton-Raphson