【发布时间】:2017-02-27 00:20:03
【问题描述】:
我正在编写一个简单的程序,该程序使用 Newton-Raphson 方法计算任何给定函数的根。在这个程序中,我必须打印找到的根和进行的迭代次数。程序本身很好,我可以找到任何给定函数的根,但我无法正确计算迭代次数。它总是超过最大值 5。迭代次数或比它少 1。这是 C++ 中的代码:
#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;
double f(float x)
{
double function1;
function1 = exp(x)- 4*pow(x,2); // given function
return function1;
}
double derivative(float x)
{
double derivative1;
derivative1 = exp(x) - 8*x; // derivative of given function
return derivative1;
}
void newtonMethod(double x0, double error, int N)
{
double xNext, xPrevious, root;
int k;
xPrevious = x0;
for(int i = 0; i < N || f(xNext) > error; i++)
{
xNext = xPrevious - (f(xPrevious)/derivative(xPrevious)); // calculates the next value of x
xPrevious = xNext;
root = xNext;
k = i;
}
cout << endl;
cout << "Iterations made: " << k << endl;
cout << endl;
cout << endl;
cout << endl;
cout << "Root is: " << root << endl;
}
int main()
{
double x0, error;
int N; // max. number of iterations you can do
cout << "Enter x0: ";
cin >> x0;
cout << "Enter the error: ";
cin >> error;
cout << "Enter the max. number of iterations: ";
cin >> N;
newtonMethod(x0, error, N);
}
而且我很确定错误出在这段代码中:
;i < N || f(xNext) > error;
如果我运行这个程序并设置 N = 100,它会显示正确的根,但它会打印“Iterations made = 99”,但这是错误的。我该怎么做才能打印出正确的迭代次数?例如,对于上面程序中的函数 (e^x - 4x²),如果我输入 x0 = 0.5 且错误 = 0.0001,它应该在第四次迭代中停止。如何解决?
【问题讨论】:
-
计算机以二进制而非十进制工作。
0.0001不能用二进制精确表示,因此您可能/不会得到确切的答案。 -- 对于上面程序中的函数 (e^x - 4x²),如果我输入 x0 = 0.5 并且错误 = 0.0001,它应该在第四次迭代中停止。 -- 在你的数学书中,是的,在二进制计算机上,也许,也许不是。 -
这不是问题,但是像
double f(float x) { double function1; function1 = exp(x)- 4*pow(x,2); return function1; }这样的代码太冗长了。double f(floats x) { return exp(x) - 4 * pow(x, 2); }做同样的事情并且更容易阅读。 -
你说得对,代码部分太冗长了,但这不是重点。我用二分法编写了另一个程序,一切都运行得很好。输入数字“0.0001”不会导致意外错误。我只是不明白是什么导致了牛顿方法中的这个错误。
-
@Diego 所有这一切都归结为一个简单的事实,即浮点数并不精确。我不知道说起来有多简单。无论您是尝试实现 Newton-Raphson,还是简单地将几个数字相加,都会导致舍入错误。
标签: c++ count newtons-method