diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/integral.c | 8 | ||||
-rw-r--r-- | src/main.c | 109 | ||||
-rw-r--r-- | src/roots.c | 8 |
3 files changed, 98 insertions, 27 deletions
diff --git a/src/integral.c b/src/integral.c index d2ae11f..f791803 100644 --- a/src/integral.c +++ b/src/integral.c @@ -5,8 +5,7 @@ double accrc = 10000.0; // интеграл прямоугольниками -double int_rect(f_t f, double a, double b) { - // f(x + dx/2) * dx +double int_rect(func_t f, double a, double b) { const double dx = (b-a) / accrc; const double dx_2 = dx / 2.0; double sum = 0.0; @@ -16,8 +15,7 @@ double int_rect(f_t f, double a, double b) { } // интеграл трапециями -double int_trap(f_t f, double a, double b) { - // ( f(x) + f(x+dx) )/2 * dx +double int_trap(func_t f, double a, double b) { const double dx = (b-a) / accrc; double sum = 0.0; for (double i = a; i < b; i += dx) @@ -26,7 +24,7 @@ double int_trap(f_t f, double a, double b) { } // интегрирование параболами -double int_simp(f_t f, double a, double b) { +double int_simp(func_t f, double a, double b) { const double dx = (b-a) / accrc; const double dx_2 = dx / 2; const double dx_6 = dx / 6; @@ -1,7 +1,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <math.h> #include <unistd.h> #include <sys/fcntl.h> @@ -22,12 +21,17 @@ void *sohandle; // This will be the type of the function -typedef double(*f_t)(double); +typedef double(*func_t)(double); +typedef double(*calc2_t)(func_t, double, double); +typedef double(*calc3_t)(func_t, double, double, double); +typedef double(*calc4_t)(func_t, double, double, double, double); + +// для выбора того, что делать с функцией enum optype { // решение уравнений SOL_BINSR, // дихтомии - SOL_HORDE, // хорды + SOL_CHORD, // хорды SOL_NEWTN, // касательные SOL_ITERN, // итерации // численное интегрирование @@ -36,8 +40,28 @@ enum optype { INT_SIMP, // симпсон }; +struct funcdescr { + void *f; + int argc; + const char *descr; +}; + +#define DESCR2 "начало и конец области интегрирования\n" +#define DESCR3 "начальное приближение, допустимую погрешность корня и невязку\n" +#define DESCR4 "левую и правую границы поиска, допустимую погрешность корня и невязку\n" + +static struct funcdescr functions[] = { + [SOL_BINSR] = {&sol_binsr, 4, DESCR4}, + [SOL_CHORD] = {&sol_chord, 4, DESCR4}, + [SOL_NEWTN] = {&sol_newtn, 3, DESCR3}, + [SOL_ITERN] = {&sol_itern, 3, DESCR3}, + [INT_RECT] = {&int_rect, 2, DESCR2}, + [INT_TRAP] = {&int_trap, 2, DESCR2}, + [INT_SIMP] = {&int_simp, 2, DESCR2}, +}; + // Function that reads Your function, compiles and loads it. -f_t input_and_compile(void) { +func_t input_and_compile(void) { puts("Напечатайте функцию от x используя синтаксис С и функции библиотеки cmath: \n" "(например, 'atan(x) / (1-exp(2*x))').\n" "Закончите ввод, нажав enter." BLINK_TERM); @@ -67,7 +91,7 @@ f_t input_and_compile(void) { // load dynamic library sohandle = dlopen(FIFO_NAME, RTLD_NOW); if (!sohandle) return NULL; - f_t ret = dlsym(sohandle, SYMNAME); + func_t ret = dlsym(sohandle, SYMNAME); // free resources and return free(buffer); @@ -77,22 +101,71 @@ f_t input_and_compile(void) { // Prompts user to choose input method enum optype get_optype(void) { - return INT_SIMP; +prompt_init: + fputs("Что вы хотите сделать с функцией?\n" + "\t1: решить уравнение f(x) = x\n" + "\t2: решить уравнение f(x) = 0\n" + "\t3: численно вычислить интеграл f(x)\n" + "Введите число: ", stdout); + char c; + switch (getchar()-'0') { + case 1: return SOL_ITERN; + + case 2: + prompt_sol: + fputs("\nКаким методом?\n" + "\t1: дихтомии (двоичный поиск)\n" + "\t2: хорд\n" + "\t3: касательных (Ньютона)\n" + "Введите число:", stdout); + c = getchar() - '0'; + if (c <= 0 || c > 3) goto prompt_sol; + return SOL_BINSR + c - 1; + + case 3: + prompt_int: + fputs("\nКаким методом?\n" + "\t1: прямоугольников\n" + "\t2: трапеций\n" + "\t3: Симпсона (парабол)\n" + "Введите число: ", stdout); + c = getchar() - '0'; + if (c <= 0 || c > 3) goto prompt_int; + return INT_RECT + c - 1; + + default: + puts("\nОшибка: ведите число от 1 до 3"); + goto prompt_init; + } } -int main(int argc, char *argv[]) { - (void)argc; (void)argv; - f_t f = input_and_compile(); +int main(void) { + func_t f = input_and_compile(); if (!f) goto exit; - double sln = sol_binsr(f, 0, 10, 0.001, 0.001); - printf("%lf\n", sln); - sln = sol_binsr(f, 0, 10, 0.001, 0.001); - printf("%lf\n", sln); - sln = sol_newtn(f, 5, 0.001, 0.001); - printf("%lf\n", sln); - sln = sol_itern(f, 0, 0.001, 0.001); - printf("%lf\n", sln); - + struct funcdescr descr = functions[get_optype()]; + double a, b, c, d; + printf("Введите %i аргумента через пробел:\n\t%s\n", descr.argc, descr.descr); + double res; + switch (descr.argc) { + case 2: + scanf("%lf %lf", &a, &b); + res = ((calc2_t)descr.f)(f, a, b); + break; + case 3: + scanf("%lf %lf %lf", &a, &b, &c); + res = ((calc3_t)descr.f)(f, a, b, c); + break; + case 4: + scanf("%lf %lf %lf %lf", &a, &b, &c, &d); + res = ((calc4_t)descr.f)(f, a, b, c, d); + break; + default: __builtin_unreachable(); + } + if (!is_root_ok()) { + fputs("Корень не посчитан из-за ограничений метода\n", stderr); + goto exit; + } + printf("Результат: %lf\n", res); exit: dlclose(sohandle); return 0; diff --git a/src/roots.c b/src/roots.c index 0aef762..f07240e 100644 --- a/src/roots.c +++ b/src/roots.c @@ -10,7 +10,7 @@ char is_root_ok(void) { } // метод дихтомии -double sol_binsr(f_t f, double a, double b, double ex, double ey) { +double sol_binsr(func_t f, double a, double b, double ex, double ey) { if (copysign(1.0, f(a)) == copysign(1.0, f(b))) { root_ok = 0; return NAN; @@ -27,7 +27,7 @@ double sol_binsr(f_t f, double a, double b, double ex, double ey) { } // метод хорд -double sol_chord(f_t f, double a, double b, double ex, double ey) { +double sol_chord(func_t f, double a, double b, double ex, double ey) { if (copysign(1.0, f(a)) == copysign(1.0, f(b))) { root_ok = 0; return NAN; @@ -46,7 +46,7 @@ double sol_chord(f_t f, double a, double b, double ex, double ey) { } // метод касательных (Ньютона) -double sol_newtn(f_t f, double x0, double ex, double ey) { +double sol_newtn(func_t f, double x0, double ex, double ey) { const double dx = 1e-6; double diff = x0+2*ex; @@ -71,7 +71,7 @@ double sol_newtn(f_t f, double x0, double ex, double ey) { } // метод итераций -double sol_itern(f_t f, double x0, double ex, double ey) { +double sol_itern(func_t f, double x0, double ex, double ey) { const double dx = 1e-6; double diff = x0 + 2*ex; |