Рекурсивная функция root: нахождение корня уравнения методом деления отрезка пополам - C (СИ)
Формулировка задачи:
Помогите пожалуйста описать рекурсивную функцию root(f,a,b,eps), которая методом деления отрезка пополам находит с точностью eps корень уравнения f(x)=0 на отрезке [a,b]. (Считать, что eps>0, a>b, f(a)*f(b)<0). Найти с ее помощью один корень уравнения sin(x)=0.5
Решение задачи: «Рекурсивная функция root: нахождение корня уравнения методом деления отрезка пополам»
textual
Листинг программы
#include<stdio.h>
#include<math.h>
double roof(double (*f)(double x),double a,double b,double eps);
double sinx(double x)
{
return sin(x)-0.5;
}
int main(void)
{
double a=0.0,b=3.0,eps;
printf("Enter eps: ");
scanf("%lf",&eps);
printf("x=%lf\n",roof(sinx,a,b,eps));
return 0;
}
double roof(double (*f)(double x),double a,double b,double eps)
{
double c=(a+b)/2;
if(fabs(b-a)<eps)
return c;
if(f(a)*f(c)<0)
return roof(f,a,c,eps);
return roof(f,c,b,eps);
}
Объяснение кода листинга программы
- Включаем необходимые заголовочные файлы
<stdio.h>- для ввода и вывода данных<math.h>- для использования математических функций
- Определяем функцию
roof, которая принимает аргументы:double (*f)(double x)- указатель на функцию, которую мы будем использовать для поиска корняdouble a- интервал поиска корня, в котором левая граница является началом интервала, а правая - концом интервалаdouble b- интервал поиска корняdouble eps- требуемая точность
- Определяем вспомогательную функцию
sinx, которая принимает аргументdouble xи возвращает значениеsin(x)-0.5 - В функции
mainмы:- Задаем начальные значения интервала поиска корня
- Запрашиваем у пользователя значение требуемой точности
eps - Вызываем функцию
roofс передачей аргументовsinx,a,b,eps - Выводим результат на экран
- В функции
roofмы:- Вычисляем средний элемент интервала
c - Проверяем условие для завершения рекурсии: если разница между
bиaменьше заданной точностиeps, то возвращаем значениеc - Проверяем знак значения функции
fв точкеaиc, если они имеют разный знак, то рекурсивно вызываем функциюroofс передачей аргументовf,a,c,eps - Если функция
fв точкеaиcимеет одинаковый знак, то рекурсивно вызываем функциюroofс передачей аргументовf,c,b,eps
- Вычисляем средний элемент интервала
- Значения переменных при входе в функцию
roofс аргументамиsinx,a=0.0,b=3.0,eps=0.0001:double (*f)(double x)- указывает на функциюsinxdouble a- равно 0.0double b- равно 3.0double eps- равно 0.0001
- Значения переменных в цикле рекурсии функции
roof:double c- в каждой итерации рекурсии вычисляется новое значение среднего элемента интервалаc- Условие для завершения рекурсии
if(fabs(b-a)<eps)может быть истинным только в случае, когда интервал поиска корня будет достаточно мал, чтобы его можно было считать элементарным - В каждой итерации рекурсии вызывается функция
fс аргументамиaиc, и проверяется знак возвращаемого значения - Значение переменной
cпередается в качестве нового аргумента для вызова функцииroofв случае рекурсивного вызова
- Возвращаемое значение функции
roofпри входе с аргументамиsinx,a=0.0,b=3.0,eps=0.0001будет равно корню уравненияsin(x)=0.5, которое находится в интервале[0.0, 3.0].