二分法によって関数根を見つける原理は次のとおりです。連続関数f(x)が区間[a、b]の2つの端点で異なる符号をとる場合、つまりf(a)f(b)<0の場合、この区間内にあります少なくとも1つのルートr、つまりf(r)= 0があります。
二分法の手順は次のとおりです。
間隔の長さを確認し、指定されたしきい値よりも小さい場合は停止し、間隔の中点(a + b)/ 2を出力します。それ以外の
場合は、f(a)f(b)<0の場合、中点f((a + b )/ 2);
f((a + b)/ 2)が正確に0の場合、(a + b)/ 2が必要なルートであり、それ以外の
場合f((a + b)/ 2)およびf(a)同じ符号は、根が区間[(a + b)/ 2、b]にあることを意味し、a =(a + b)/ 2とすると、サイクルが繰り返されます;
f((a + b)/ 2)とf(b)の場合同じ符号は、根が区間[a、(a + b)/ 2]にあり、b =(a + b)/ 2とし、サイクルを繰り返すことを意味します。
このトピックでは、与えられた3次多項式f(x)= a 3 x 3 + a 2 x 2 + a 1 x + a 0の根を与えられた区間[a、b]内で計算するプログラムを書く必要があります。
入力フォーマット:最初の行に
順次多項式を与え、2番目の行に区間の端点aとbを与える4つの係数a 3、a 2、a 1、a 0を入力します。問題は、多項式が特定の区間で単一の根を持つことを保証することです。
出力形式:
区間内の多項式の根を小数第2位までの1行で出力します。
入力例:
3 -1 -3 1
-0.5 0.5
出力例:
0.33
さらに面倒なことなく、まずコードに移動します
#define _CRT_SECURE_NO_DEPRECATE 0
#include<stdio.h>
#include<stdlib.h>
double a0, a1, a2, a3;
double target(double n){
double f;
f = a3*(n*n*n) + a2*(n*n) + a1*n + a0; //计算函数值
return f;
}
int main(){
double a, b;
int i = 0;
scanf("%lf %lf %lf %lf", &a3, &a2, &a1, &a0);
scanf("%lf %lf", &a, &b);
double f1, f2, n, f;
f1 = target(a);
f2 = target(b);
if (f1*f2 < 0){
n = (a + b) / 2;
f = target(n);
while (1){
i++;
if (f == 0){ //f正好为0,则n就是要求的根
printf("%.2lf", n);
break;
}
if (i == 100){ //当出现求不尽的情况时
printf("%.2lf", n);
break;
}
else if (f*f1 < 0){ //如果f与f1异号,则说明根在区间[a,n],令b=n,重复循环
b = n;
n = (n + a) / 2;
}
else if (f*f2 < 0){ //如果f与f2异号,则说明根在区间[n,b],令a=n,重复循环
a = n;
n = (n + b) / 2;
}
f = target(n);
}
}
else if (f1 == 0){ //区间端点是根的情况
printf("%.2lf", a);
}
else if (f2 == 0){ //区间端点是根的情况
printf("%.2lf", b);
}
system("pause");
return 0;
}