二分法求一元三次方程的一个实数根

一元一次方程的一般形式是$ax+b=0$,很容易解得$x=-\frac{b}{a}$。对于一元二次方程,也有一个简单的求根公式可以解出方程的根。但是一元三次方程的求根公式较为复杂,需分情况,编写程序的复杂度比前两个要大得多。

你可能已经听说过二分查找法,在已排序的数组中查找某一个数的时间复杂度从$O(n)$降到了$O(lg
n)$。类似地,我们可以用二分法来求解一个一元三次方程的实数根。

以下是非递归版本的实现。calc函数用于计算方程取某个$x$值时方程左端的值。因为这个函数只是返回一个计算表达式的值,将其声明为内联函数,编译器可以将其展开到调用处,节省调用函数耗费的时间。solve函数的参数L、R指定二分查找的范围。


 1 #include <iostream>
2 #include <cstdlib>
3 #include <cmath>
4 using namespace std;
5
6 double a, b, c, d;
7
8 inline double calc(double x)
9 {
10 return a*x*x*x + b*x*x + c*x + d;
11 }
12
13 double solve(double L, double R)
14 {
15 double x = (L+R)/2, step = (R-L)/2, result;
16 while(fabs(result=calc(x)) > 0.001)
17 {
18 if(result < 0)
19 x += step;
20 else if(result > 0)
21 x -= step;
22 step /= 2;
23 }
24 return x;
25 }
26
27 int main()
28 {
29 cin >> a >> b >> c >> d;
30 cout << solve(-10000, 10000) << endl;
31 return 0;
32 }

此算法的时间复杂度为$O(lg\frac{L+R}{2})$,和查找范围有关,与方程的系数无关。范围在-10000~+10000时,在我的Core
i3的笔记本上,平均时间只在5ms左右。

这种方法在方程系数较小且只需要得到实数根时是非常有效的。

时间: 2024-10-12 14:20:31

二分法求一元三次方程的一个实数根的相关文章

用弦截法求一元三次方程的根x^3-5x^2+16x-80=0 ;带注释!

//用弦截法求一元三次方程的根x^3-5x^2+16x-80=0 #include<stdio.h>#include<math.h> float f(float x) //定义子函数f(x) = x^3-5x^2+16x-80,当f(x) →0时,则x即为所求的实数根:  {     float y;     y=((x-5.0)*x+16.0)*x-80.0;     return(y);          //返回f(x)的值  }    float xpoint( float

弦截法求一元三次方程的近似解

1 #include<stdio.h> 2 #include<math.h> 3 4 //计算一元三次方程的根大致分布位置 5 6 //计算的方程为 x*x*x-8*x*x+12*x-30=0 7 8 //计算函数值 9 float f(float x) 10 { 11 return ((x-8.0)*x+12.0)*x-30.0; 12 } 13 14 //计算弦与坐标x轴的交点 15 16 float xpoint(float x1,float x2) 17 { 18 retu

一元二次、三次、四次方程的实数根(c语言)

1 #include <math.h> 2 /************************************************* 3 Function: solve_quadratic_equation 4 Description: 求一元二次方程(a*x^2 + b*x + c = 0)的所有实数根 5 Input: 方程的系数 p = {c, b, a} 6 Output: 方程的所有实数根x 7 Return: 实数根的个数 8 Author: 枫箫 9 Version:

二分法求三次方程的根

二分法求根 #include "stdio.h" #define f(x) a*x*x*x+b*x*x+c*x+d int main() { freopen("in.txt", "r", stdin); int a, b, c, d; double x1, x2, x, y1, y2, y; while (scanf("%d%d%d%d", &a, &b, &c, &d) != EOF) { x

求一元二次方程的根

描述 利用公式x1 = (-b + sqrt(b*b-4*a*c))/(2*a), x2 = (-b - sqrt(b*b-4*a*c))/(2*a)求一元二次方程ax2+ bx + c =0的根,其中a不等于0. 输入输入一行,包含三个浮点数a, b, c(它们之间以一个空格分开),分别表示方程ax2 + bx + c =0的系数.输出输出一行,表示方程的解.若b2 = 4 * a * c,则两个实根相等,则输出形式为:x1=x2=....若b2 > 4 * a * c,则两个实根不等,则输出

求一元二次函数的根

总时间限制:1000ms内存限制:65536kB 描述 利用公式x1 = (-b + sqrt(b*b-4*a*c))/(2*a), x2 = (-b - sqrt(b*b-4*a*c))/(2*a)求一元二次方程ax2+ bx + c =0的根,其中a不等于0. 输入 输入一行,包含三个浮点数a, b, c(它们之间以一个空格分开),分别表示方程ax2 + bx + c =0的系数. 输出 输出一行,表示方程的解.若b2 = 4 * a * c,则两个实根相等,则输出形式为:x1=x2=...

Openjudge-计算概论(A)-求一元二次方程的根

描述: 利用公式x1 = (-b + sqrt(b*b-4*a*c))/(2*a), x2 = (-b - sqrt(b*b-4*a*c))/(2*a)求一元二次方程ax2 + bx + c =0的根,其中a不等于0.输入第一行是待解方程的数目n. 其余n行每行含三个浮点数a, b, c(它们之间用空格隔开),分别表示方程ax2 + bx + c =0的系数.输出输出共有n行,每行是一个方程的根:若是两个实根,则输出:x1=...;x2 = ...若两个实根相等,则输出:x1=x2=...若是两

1-4-20:求一元二次方程的根

描述 利用公式x1 = (-b + sqrt(b*b-4*a*c))/(2*a), x2 = (-b - sqrt(b*b-4*a*c))/(2*a)求一元二次方程ax2+ bx + c =0的根,其中a不等于0. 输入 输入一行,包含三个浮点数a, b, c(它们之间以一个空格分开),分别表示方程ax2 + bx + c =0的系数. 输出 输出一行,表示方程的解.若两个实根相等,则输出形式为:x1=x2=....若两个实根不等,则输出形式为:x1=...;x2 = ...,其中x1<x2.若

Openjudge ch0111/t6253 用二分法求方程的根

这题只是考你最后有没有(r-l)/2而已…… 总时间限制: 1000ms 内存限制: 65536kB 描述 用二分法求下面方程在(-10, 10)之间的一个根. 2x3- 4x2+ 3x- 6 = 0 输入 一个小于1的非负实数e,它的值表示所能允许的误差 输出 一个实数,其值为求得的一个根,要求精确到小数点后8位.若该区间上没有根,则输出“No Solution” 样例输入 0 样例输出 2.00000000 提示 对于一个连续函数f(x),若f(a)*f(b) <= 0,则f(x)在区间[a