二分法和牛顿迭代法解方程实根,详解
目录
题目编辑
二分法
解题思路
代码以及运行截图
牛顿迭代法
解题思路
代码和运行截图
题目
编写程序,分别用二分法和牛顿迭代法求解方程x3 – 3x – 1 = 0在x = 2附近的实根,要求计算精确到小数点后7 位数字为止,并将求出的近似结果与理论值2cos20° 比较误差大小。
设二分法的初始迭代区间为 [1, 3],牛顿迭代法的起点为4。
二分法
解题思路
根据中学知识,我们知道一个函数,比如题目里的这个,当x的取值满足这个函数为0,即满足题目条件,为实根。
如果我们取x1为a,x2为b,那么如果fx1乘以fx2小于0,那么x1和x2之间至少有一个解。
题目告诉了我们区间为1到3,我们取a为1,b为3,mid一直为a+b再除以2。
如果fmid为0,即为解。
如果fmid和fa同号,解就在mid和b之间,让a变为mid
如果fmid和fb同号,解就在mid和a之间,让b变为mid
由于题目要求精度要到小数点后七位,所以判断条件可以为b - a < 1e-8,表示理论值,可以使用这串代码theo = 2 * cos(20 * M_PI / 180)
可以使用 cout << fixed << setprecision(7);控制c++里面输出的数保留到小数点后六位。
代码以及运行截图
#include<iostream>
#include<bits/stdc++.h>
using namespace std;double func(double x) {return x*x*x - 3*x - 1;
}int main()
{const double theo = 2 * cos(20 * M_PI / 180); // 理论值 2cos20°double tol = 1e-8; // 精确到小数点后7位需要容差1e-8double a = 1;double b = 3;double mid;while((b - a) >= tol) {mid = (a + b) / 2;if(func(mid) == 0.0) {break;}else if(func(mid) * func(a) > 0)a = mid;else if(func(mid) * func(b) > 0)b = mid;}cout << "使用二分法求解:" << endl;cout << fixed << setprecision(7);cout << "近似根: " << mid << endl;cout << "理论值: " << theo << endl;cout << "绝对误差: " << abs(mid - theo) << endl << endl;return 0;
}
牛顿迭代法
解题思路
起点为4,设置迭代次数为100次
迭代的核心代码为x_new = x - fx / dfx;然后不断逼近实根,最终得到一个解。
代码和运行截图
#include<iostream>
#include<bits/stdc++.h>
using namespace std;double func(double x) {return x*x*x - 3*x - 1;
}double deriv(double x) {return 3*x*x - 3;//导数
}int main()
{const double theo = 2 * cos(20 * M_PI / 180); // 理论值 2cos20°double iteration = 0;double tolerance = 1e-8; // 精确到小数点后7位需要容差1e-8double x = 4;//牛顿迭代法起点while(iteration < 100) {//迭代次数在一百次以内double fx = func(x);double dfx = deriv(x);if (abs(fx) < tolerance) {break;}if (dfx == 0) {cout << "导数为零,无法继续迭代。" << endl;}double x_new = x - fx / dfx;if (abs(x_new - x) < tolerance) {break;}x = x_new;iteration++;}//牛顿迭代法求解cout << fixed << setprecision(8);cout << "使用牛顿迭代法求解:" << endl;cout << "近似根: " << x << endl;cout << "理论值: " << theo << endl;cout << "绝对误差: " << abs(x - theo) << endl;return 0;
}