某葉C語言學習上重大的一步——一元三次方程求解
目前某葉編的最難的程式了......感覺算是跨越吧,之前最難的是一元二次方程求解,雖然是最“難”的,只是因為最長,但是寫起來還是很輕鬆的
不過一元三次方程可一點都不輕鬆,很累,因為沒學過一元三次方程解法,所以需要百度,不過在C語言學習的書上找到了解法,要用牛頓迭代法求......
百度娘處充電,勉勉強強算是能看懂牛頓迭代法了,可能根本沒看懂,不過至少知道怎麼算了
解法思路:
先把求與X軸交點座標公式放著免得忘記了
x= x1f(x2)-x2f(x1)/f(x2)-f(x1)
之後比較x1的y1值和x2的y2值,如果兩個為異號,那麼兩個x之間一定有方程的根
如果同號,那麼繼續輸入直到異號為止
這個時候用求交點座標公式求出交點座標x,它的y值同樣代入求出
再次比較y與y1值,如果異號那麼x與x1之間必有方程根
如果同號那麼x與x2之間必有方程根
迴圈以上直到y的絕對值小於一個非常小的數,也就近似為0的時候,輸出x值既為方程根......
理好了解法思路就不怕了,因為這個程式的關鍵就是我沒學過解法,現在解法清楚了就開始編了
寫了很多的函式,對我來說很複雜,所以註釋比較多,省的以後自己都看不懂了......
書上給的例子方程式x^3-5x^2+16x-80=0給出的一個解x=5,圖2反應出來了......
#include <stdio.h>#include <math.h>
#include <conio.h>
float a,b,c,d; //定義外部變數,使全域性可以呼叫
float f(float x) //x函式
{
floaty;
y=a*x*x*x+b*x*x+c*x+d;
returny;
}
float xpoint(float x1,float x2) //求弦與x軸交點座標
{
floaty;
y=(x1*f(x2)-x2*f(x1))/(f(x2)-f(x1));
returny;
}
float root(float x1,float x2) //求根函式
{
floatx,y,y1;
y1=f(x1);//y1為x1縱座標
do
{
x=xpoint(x1,x2); //求x1與x2之間弦與x軸交點賦值於x
y=f(x); //代入方程中求得y
if(y*y1>0) //判斷y與y1是否同號
{
x1=x;
y1=y;
}
else
x2=x;
}
while(fabs(y)>=0.00001); //設定精度
return(x);
}
void main() //主函式
{
floatx1,x2,f1,f2,x;
printf("請輸入一元三次方程標準形式ax^3+bx^2+cx+d=0中 ");
printf("a bc d的值,用空格隔開\n");
scanf("%f %f%f%f",&a,&b,&c,&d);//獲取abcd值並賦值
do
{
printf("輸入x1 x2值,用空格隔開:\n");
scanf("%f %f",&x1,&x2);
f1=f(x1);
f2=f(x2);
if(f1*f2>=0)
printf("x1x2之間無方程根,請重新輸入\n");
}
while(f1*f2>=0); //do...while函式為了得到x1與x2的函式值為異號,這樣x1 x2中才有根
x=root(x1,x2); //將x1 x2送到求根函式中返回值賦到x中
printf("方程中的一個根為%g\n",x);
getch();
}
執行截圖:
附:兩分法解方程 求一個實根
演算法:
用兩分法求方程 y=f(x) = 0 的近似根。
找兩個近似根x1和x2,使有
y1和y2異號,如
y1< 0,y2> 0
求新的近似根, x =(x1 + x2)/2
若 y=f(x)<0,則 x1= x; y1= f(x);
否則,x2= x; y2= f(x);
根所在的區間縮小一半。
重複計算新的近似根並估計偏差
直至 | x2– x1|<1e-10。
牛頓法解方程 求一個實根
演算法:方程y=f(x)=0
求在x0附近的一個實根。
選一個近似根x0,求y0 =f(x0);
過y0作f(x)的切線,交橫軸於x1,
以