diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7e42c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# C++ language server +.ccls +.ccls-cache/* + +# Vscode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json + +# Binaries +a.out diff --git a/functions.cpp b/functions.cpp new file mode 100644 index 0000000..550623d --- /dev/null +++ b/functions.cpp @@ -0,0 +1,29 @@ +#include + +// 1.1 e^(x - 1) - x^3 - x +double function_1(double x) +{ + return std::exp(x - 1) - std::pow(x, 3) - x; +} + + +// 1.2 1 / (3 + sin(3.6x)) +double function_2(double x) +{ + return 1 / (3 + std::sin(3.6 * x)); +} + + +// 1.3 arccos(x) - √(1 - 0.3x^3) +double function_3(double x) +{ + return std::acos(x) - std::sqrt(1 - 0.3 * std::pow(x, 3)); +} + + +// 1.9 0.25x^3 + x - 2 +double function_9(double x) +{ + return 0.25 * std::pow(x, 3) + x - 2; +} + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..f10d8ce --- /dev/null +++ b/main.cpp @@ -0,0 +1,101 @@ +#include +#include + +#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; +} + +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; +}