Язык Си в примерах/Корень уравнения: различия между версиями

Содержимое удалено Содержимое добавлено
мНет описания правки
м Добавил reusable вариант вычисления корня уравнения
Строка 54:
* Сколько требуется шагов, чтобы начиная с отрезка длины <math>r-l=2</math> дойти до отрезка длины меньше <math>10^{-10}</math>? Сколько требуется шагов, чтобы найти корень с точностью до 100 знаков после запятой?
* В случае деления попалам у нас есть нижняя и верхняя граница для значения корня. С каждым шагом эти границы сближаются. В методе Ньютона нахождения корня уравнения у нас имеется одно число ''x'' &mdash; текущее приближение корня. И следующее приближение получается по следующему алгоритму: находим точку на графике с абциссой x и проводим из неё касательную к графику; абcцисса точки пересечения касательной с осью абцисс будет новым значением ''x''. Так делается до тех пор, пока новое ''x'' отличается от старого на число меньше, чем <math>10^{-10}/2</math>. Реализуйте этот алгоритм. Для этого вам понадобится определить еще одну функцию, которая возвращает значение производной <math>f'(x) = (e^x-x-2)' = e^x-1</math>.
 
 
==Универсальная функция вычисления корня==
 
В рассмотренном нами примере вычисляется нуль вполне конкретной функции f(x) = exp(x) - 2 - x.
Следуя идеологии [[w:Reuse|resuse]], полезно сделать функцию, которая может находить нули произвольной данной функции.
Для этого нужно научится передавать функцию в качестве аргумента --- это возможно, и совсем несложно:
 
/* Универсальная функция вычисление корня уравнения f(x) = 0 */
#include <stdio.h>
#include <math.h>
#define EPS 1e-16
double root(double l, double r, double (*f)(double)) {
double c;
while( r - l > EPS ) {
c = ( l + r ) / 2;
if( f(c) * f(r) < 0 )
l = c;
else
r = c;
}
return l;
}
double f1(double x) {return cos(x) - 3*x; }
double f2(double x) {return exp(x) - x - 2; }
int main() {
printf("root1 = %lf\n", root(0, 2, f1)); // вычисляем и выводим корень уравнения f1(x) = 0
printf("root2 = %lf\n", root(0, 2, f2)); // вычисляем и выводим корень уравнения f2(x) = 0
return 0;
}
 
 
Вывод программы выглядит следующим образом:
 
root1 = 0.316751
root2 = 1.146193