123 lines
3.7 KiB
C++
123 lines
3.7 KiB
C++
#include <iostream>
|
||
#include <cmath>
|
||
|
||
#include "functions.cpp"
|
||
|
||
// left - левая часть интервала
|
||
// right - правая часть интервала
|
||
// error - желаемая погрешность
|
||
// f - функция из задания
|
||
|
||
bool doesRootExist(double left, double right, double (*f)(double x))
|
||
{
|
||
// Функция для проверки существования корня функции в интервале.
|
||
// left - левая граница
|
||
// right - правая граница
|
||
// f - функция
|
||
//
|
||
if (f(left) * f(right) > 0)
|
||
{
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
double bisectionMethod(double left, double right, double error, double (*f)(double x))
|
||
{
|
||
// Метод половинного деления для нахождения корня функции f
|
||
// в интервале [left, right] с погрешностью error.
|
||
//
|
||
// left - левая граница
|
||
// right - правая граница
|
||
// error - желаемая погрешность
|
||
// f - функция
|
||
|
||
double center;
|
||
|
||
// Повторяем сужение до тех пор, пока расстояние центра center
|
||
// от корня функции f не достигнет желаемой погрешности error
|
||
while (std::fabs(right - left) > error)
|
||
{
|
||
center = left + (right-left)/2;
|
||
|
||
if (f(left) * f(center) < 0)
|
||
{
|
||
// Если ушли слишком далеко влево, то установим центр
|
||
// на правую границу
|
||
right = center;
|
||
}
|
||
else
|
||
{
|
||
// Ушли слишком далеко вправо, устанавливаем центр
|
||
// на левой границе
|
||
left = center;
|
||
}
|
||
}
|
||
|
||
return center;
|
||
}
|
||
|
||
// Метод хорд
|
||
double chordMethod(double left, double right, double error, double (*f)(double x))
|
||
{
|
||
while (std::fabs(right - left) > error)
|
||
{
|
||
left = left - (right - left) * f(left) / (f(right) - f(left));
|
||
right = right - (left - right) * f(right) / (f(left) - f(right));
|
||
}
|
||
return right;
|
||
}
|
||
|
||
double chordMethod2(double left, double right, double error, double (*f)(double))
|
||
{
|
||
double center;
|
||
|
||
while(std::fabs(right - left) > error)
|
||
{
|
||
center = ( f(right) * left - f(left) * right) / ( f(right) - f(left) );
|
||
|
||
if( f(left) * f(center) < 0)
|
||
{
|
||
right = center;
|
||
}
|
||
else
|
||
{
|
||
left = center;
|
||
}
|
||
}
|
||
|
||
return center;
|
||
}
|
||
|
||
int main()
|
||
{
|
||
// Включим языковые настройки для корректного отображения русских символов
|
||
setlocale(LC_ALL, "Russian");
|
||
|
||
auto function = &function_1;
|
||
double L = 0;
|
||
double R = 1;
|
||
double E = 0.0000001;
|
||
|
||
// Проверим, что может ли существовать корень в данном интервале
|
||
if (!doesRootExist(L, R, function))
|
||
{
|
||
std::printf("Нет корня в данном интервале\n");
|
||
return 0;
|
||
}
|
||
|
||
// Рассчитаем результат для функции с помощью обоих методов
|
||
double chordMethodResult = chordMethod(L, R, E, function);
|
||
double bisectionMethodResult = bisectionMethod(L, R, E, function);
|
||
|
||
// Отобразим результат
|
||
std::printf("Решение методом половинного деления: %f\n", bisectionMethodResult);
|
||
std::printf("Решение методом хорд: %f\n", chordMethodResult);
|
||
|
||
// Выполним проверку
|
||
std::printf("(Bisection) При x=%f: f(x)=%f\n", bisectionMethodResult, function(bisectionMethodResult));
|
||
std::printf("(Chord) При x=%f: f(x)=%f\n", chordMethodResult, function(chordMethodResult));
|
||
|
||
return 0;
|
||
}
|