aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Makefile37
-rw-r--r--README.md44
-rw-r--r--compile_flags.txt2
-rw-r--r--hof_example.c33
-rw-r--r--include/integral.h12
-rw-r--r--include/roots.h15
-rw-r--r--main_1.c89
-rw-r--r--main_23.c182
-rw-r--r--src/integral.c38
-rw-r--r--src/main.c99
-rw-r--r--src/roots.c94
-rw-r--r--test_f.c5
13 files changed, 339 insertions, 314 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ae535a6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+compile_flags.txt
+build/
+*.o
diff --git a/Makefile b/Makefile
index 508c7de..b3e5061 100644
--- a/Makefile
+++ b/Makefile
@@ -1,33 +1,24 @@
-all: t1_a t1_b t23 test.so
+CFLAGS = -O2 -Wall -Wextra -Werror -Iinclude
-T2FLAGS := -Wall
+all: task4
-ifneq ($(OS),Windows_NT)
- T2FLAGS += -DDYNAMIC_LOAD
- T2LINKS = -lm -ldl
- ifneq (, $(shell which gnuplot))
- T2FLAGS += -DPIPE_GNUPLOT
- ifeq (, ${DISPLAY})
- T2FLAGS += -DTERMINAL_PLOT
- endif
- endif
-endif
+build:
+ mkdir -p build
-t1_a: main_1.c
- $(CC) -DPROG_SINUS_SUM $^ -o $@
+build/roots.o: src/roots.c build
+ $(CC) $(CFLAGS) -c -o $@ $<
-t1_b: main_1.c
- $(CC) -DPROG_MONTE_CARLO $^ -o $@
+build/integral.o: src/integral.c build
+ $(CC) $(CFLAGS) -c -o $@ $<
-t23: main_23.c
- $(CC) $(T2FLAGS) $^ -o $@ $(T2LINKS)
+task4: build/roots.o build/integral.o src/main.c
+ $(CC) $(CFLAGS) -o $@ $^ -lm -ldl
-test.so: test_f.c
- $(CC) -fPIC -fPIE -shared $^ -o $@
+.PHONY: run clean
-.PHONY: clean
+run: task4
+ ./task4
clean:
- rm -rf t1_a t1_b t23 test.so
-
+ rm -f build/*.o task4
diff --git a/README.md b/README.md
index b39a043..b3b4bae 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,29 @@
-# сборка
-1. `make`
-2. готово.
-# запуск
-## задание 1:
-`./t1_a` и `./t1_b`. Это старые задания с рядом тейлора синуса и с методом монте-карло.
-Аргументы командной строки не требуются
-## задание 2:
-`./t23 -h` выведет помощь. необходимые флаги: `-o`, `-f`.
-Если на компе есть программа gnuplot (в переменной PATH), программа построит в ней график.
-Если gnuplot нет на компе, то в Makegfile найдите флаг `-DPIPE_GNUPLOT` и удалите его.
-## задание 3:
-`./t23 -h` выведет помощь. флаг `-d` (differentiate) активирует 3 задание. необходимые
-для 3 задания флаги: `-o`, `-f`, `-x`.
-про gnuplot то же самое, что и для 2 задания
+# ВАЖНО
+## Запуск
+Файл `main.c` РАБОТАЕТ ТОЛЬКО НА ЛИНУКСЕ. Все алгоритмы работают на любой платформе, но в функции main есть вещи (например, ввод функции на языке С), не осуществимые на винде.
+Поэтому, если вы хотите ЗАПУСТИТЬ программу целиком - либо берите линукс, либо пишите свою функцию main, которая будет использовать алгоритмы из файлов `roots.c` или `integrals.c`
+## А что такое `func_t f` в аргументах?
+Я передаю интегрируемую функцию как аргумент в свою функцию. Да, вы можете передавать функции в функции. Это называется функции высшего порядка, пример использования есть в `hof_example.c`.
+файл `hof_example.c` запустится на любой ОС без изменений
+# Задание 4
+## Описание программы
+* Вы вводите с клавиатуры функцию от переменной x, используя синтаксис Си
+* Потом вы выбираете, какое задание выполнить: решение уравнения (приравнять функцию к нулю) или выполнить численное интегрирование.
+* После этого вы выбираете способ проведения операции и вводите нужные для способа числа (интервал, начальное число и т.п.)
+* Ответ выводится на экран.
+## Файлы
+Директория `include/`: Заголовочные файлы
+Директория `src/`: Файлы имплементации (с кодом)
+`Makefile`: система сборки
+`src/main.c`: логика по вводу функции и по взаимодействию с пользователем
+`src/roots.c`: Все алгоритмы поиска корней
+`src/integral.c`: Все алгоритмы вычисления интеграла
+## Как пользоваться?
+ВСЕ ИНСТРУКЦИИ ДАЮТСЯ ПРИ ЗАПУСКЕ ПРОГРАММЫ
+Флагов командной строки нет
+1. вводите функцию
+2. вводите, что с ней делать (искать корни? интегрировать?)
+3. вводите способ (трапеции, симпсон и т.п...)
+4. вводите параметры (интервал или начальное приближение, допустимые погрешности...)
+5. получаете результат
+
diff --git a/compile_flags.txt b/compile_flags.txt
new file mode 100644
index 0000000..1919e8f
--- /dev/null
+++ b/compile_flags.txt
@@ -0,0 +1,2 @@
+ -Iinclude
+
diff --git a/hof_example.c b/hof_example.c
new file mode 100644
index 0000000..d8fee90
--- /dev/null
+++ b/hof_example.c
@@ -0,0 +1,33 @@
+// Это пример использования функций высшего порядка
+#include <stdio.h>
+#include <math.h>
+
+// Синтаксис непонятный, но так я создаю "синоним"
+// к указателю на функцию, принимающую 2 double и возвращающую double
+typedef double(*func_t)(double, double);
+
+
+// Эта функция "передаёт" аргументы в функцию и выводит результат
+void calculate_and_print(func_t function, double arg1, double arg2) {
+ printf("F(%lf, %lf) = %lf\n", arg1, arg2, function(arg1, arg2));
+}
+
+// считает сумму x и y
+double sum(double x, double y) {
+ return x + y;
+}
+
+// считает произведение x и y
+double prod(double x, double y) {
+ return x * y;
+}
+
+int main(void) {
+ // передаёшь функцию в функцию по имени,
+ // как самый обычный аргумент
+ calculate_and_print(sum, 420, 69);
+ calculate_and_print(prod, 420, 69);
+ // fmax - функция стандартной библиотеки
+ // возвращает максимальное из двух чисел
+ calculate_and_print(fmax, 420, 69);
+}
diff --git a/include/integral.h b/include/integral.h
new file mode 100644
index 0000000..e3583b8
--- /dev/null
+++ b/include/integral.h
@@ -0,0 +1,12 @@
+#ifndef JUSTANOTHERCATGIRL_TASK4_INTEGRAL
+#define JUSTANOTHERCATGIRL_TASK4_INTEGRAL
+
+typedef double(*f_t)(double);
+
+extern double accrc;
+
+double int_rect(f_t f, double a, double b);
+double int_trap(f_t f, double a, double b);
+double int_simp(f_t f, double a, double b);
+
+#endif //JUSTANOTHERCATGIRL_TASK4_INTEGRAL
diff --git a/include/roots.h b/include/roots.h
new file mode 100644
index 0000000..5307991
--- /dev/null
+++ b/include/roots.h
@@ -0,0 +1,15 @@
+#ifndef JUSTANOTHERCATGIRL_TASK4_ROOTS
+#define JUSTANOTHERCATGIRL_TASK4_ROOTS
+
+typedef double(*f_t)(double);
+
+extern char root_ok;
+
+char is_root_ok(void);
+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_newtn(f_t f, double x0, double ex, double ey);
+double sol_itern(f_t f, double x0, double ex, double ey);
+
+
+#endif // JUSTANOTHERCATGIRL_TASK4_ROOTS
diff --git a/main_1.c b/main_1.c
deleted file mode 100644
index cd84b67..0000000
--- a/main_1.c
+++ /dev/null
@@ -1,89 +0,0 @@
-#include <stdio.h>
-
-#if defined(PROG_SINUS_SUM)
-
-#define EPSILON 0.001*0.001
-#define MAX_ITERATIONS 100
-
-int main(void) {
- puts("defined macro PROG_SINUS_SUM");
- double x;
- double result;
- double last_elem;
- int i;
-
- printf("Input a number\n");
- scanf("%lf", &x);
- last_elem = result = x;
-
- for (i = 1; i < MAX_ITERATIONS; ++i) {
- last_elem = last_elem * x * x / (2*i * (2*i+1));
- if (last_elem*last_elem <= EPSILON) break;
- result += last_elem * ( (i%2 * -2) + 1 );
- }
- printf("result = %lf; iterations = %i; last_elem = %lf\n", result, i, last_elem);
- return 0;
-}
-
-#elif defined(PROG_MONTE_CARLO)
-
-#include <stdlib.h>
-#include <time.h>
-
-#define _USE_MATH_DEFINES
-#include <math.h>
-
-struct point {
- float x, y;
-};
-
-struct circle {
- // center not needed for this task
- /*struct point center;*/
- float rad;
-};
-
-char in_circle(const struct circle *c, const struct point p) {
- /*p.x -= c->x;*/
- /*p.y -= c->y;*/
- return p.x * p.x + p.y * p.y < c->rad*c->rad;
-}
-
-float calculate_pi(int iterations) {
- int in = 0, out = 0;
- int *arr[2] = {&out, &in};
- const struct circle c = {.rad = 1.0f};
- for (int i = 0; i < iterations; ++i) {
- struct point p = {
- .x = rand() % 2000000u / 1e6f - 1,
- .y = rand() % 2000000u / 1e6f - 1
- };
- ++*arr[in_circle(&c, p)];
- }
- return (float)in/iterations * 4;
-}
-
-int main(int argc, char *argv[]) {
- puts("defined macro PROG_MONTE_CARLO");
- srand(time(NULL));
- int iters;
- if (argc == 2) {
- iters = atoi(argv[1]);
- } else {
- fputs("Iterations: ", stdout);
- if (!scanf("%i", &iters)) {
- fputs("Input a valid number\n", stderr);
- return EXIT_FAILURE;
- }
- }
- float pi = calculate_pi(iters);
- float err = fabs(M_PI-pi)/M_PI;
- printf( "calculated pi: %.4f, actual pi: %.4f\n"
- "error: %.2f%%\n",
- pi, M_PI, err * 100);
- return EXIT_SUCCESS;
-}
-
-#else
- #error "define macro PROG_SINUS_SUM or PROG_MONTE_CARLO in compilation flags"
-#endif
diff --git a/main_23.c b/main_23.c
deleted file mode 100644
index 8460415..0000000
--- a/main_23.c
+++ /dev/null
@@ -1,182 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-struct dval { double x, y; };
-typedef double (*func_t)(double);
-
-#ifdef PIPE_GNUPLOT
- #include <unistd.h>
- #include <fcntl.h>
-
- void print_table(FILE*, const struct dval *, long int);
- /// This function is creating a 'gnuplot' pipe
- /// and writing data to it to be plotted
- void pipe_gnuplot(struct dval *table, long len) {
- FILE* gp = popen("gnuplot", "w");
- if (!gp) return;
-#ifdef TERMINAL_PLOT
- fputs("set terminal block\n", gp);
-#endif // TERMINAL_PLOT
- fputs("plot '-' with lines\n", gp);
- print_table(gp, table, len);
- fputs("e\n", gp);
- fflush(gp);
-
- getchar();
- pclose(gp);
- }
-#endif // PIPE_GNUPLOT
-
-#ifdef DYNAMIC_LOAD
- #include <dlfcn.h>
- void* handle = NULL;
-#endif // DYNAMIC_LOAD
-
-double sin2(double x) {
- double y = sin(x);
- return y*y;
-}
-double cos2(double x) {
- double y = cos(x);
- return y*y;
-}
-double __sincos(double x) {
- // sin(x)cos(x) = sin(2x)/2
- return sin(2*x)/2;
-}
-double sin2x(double x) {
- return sin(2*x);
-}
-
-/// generates the table as asked in the task.
-/// The core function for task 2
-struct dval *get_table(func_t f, double start, double end, double step, long *length) {
- long tlength = lround((end-start)/step);
- struct dval *vals = calloc(tlength, sizeof(struct dval));
- for (long i = 0; i < tlength; ++i) {
- double x = start + step * i;
- // Not accumulative because if step is too small,
- // start will never increment
- vals[i] = (struct dval){.x = x, .y = f(x)};
- }
- *length = tlength;
- return vals;
-}
-
-/// generates the table for derivative of function f.
-/// The core function for task 3
-struct dval *differentiate(func_t f, double start, double end, double step, long *length) {
- long tlength = lround((end-start)/step);
- struct dval *vals = calloc(tlength, sizeof(struct dval));
- for (long i = 0; i < tlength; ++i) {
- double x = start + step * i;
- // central difference
- double y = (f(x+step) - f(x-step))/ (2*step);
- vals[i] = (struct dval){.x = x, .y = y};
- }
- *length = tlength;
- return vals;
-}
-
-void print_table(FILE* stream, const struct dval *table, long size) {
- for (long i = 0; i < size; ++i) {
- fprintf(stream, "%lg %lg\n", table[i].x, table[i].y);
- }
-}
-
-
-void print_help(int status) {
- const char *help =
- "This program is Licensed under 'the unlicense license'\n\n"
- "Usage: ./t23 -f func_name -o output_file [-x number -h -d]\n"
- "\t-h: this help\n"
- "\t-d: differentiate function (do task 3)\n"
- "\t-f: function: either 'sin2', 'cos2', 'sincos', 'tg' or 'sin2x' .\n"
- "\t\tif compiled with -DDYNAMIC_LOAD, file name with dynamic function.\n"
- "\t-o: output file.\n"
- "\t-x: only needed with -d flag - differentiation step (the dx)\n\n"
- "NOTE: the function in dynamic library must be named 'f'.\n"
- "NOTE 2: with flag -DPIPE_GNUPLOT output will be piped in gnuplot\n";
- puts(help);
- exit(status);
-}
-
-/// Get the function based on the command line flags - either use
-/// existing or load one from dynamic library
-func_t get_function(const char* name) {
- if (!strcmp(name, "cos2"))
- return &cos2;
- if (!strcmp(name, "sin2"))
- return &sin2;
- if (!strcmp(name, "sincos"))
- return &__sincos;
- if (!strcmp(name, "tg"))
- return &tan;
- if (!strcmp(name, "sin2x"))
- return &sin2x;
-#ifndef DYNAMIC_LOAD
- fputs("ERROR: unknown function. To use dynamic loading, compile with `-DDYNAMIC_LOAD`.\n", stderr);
- exit(EXIT_FAILURE);
-#else // DYNAMIC_LOAD
- handle = dlopen(name, RTLD_NOW);
- if (!handle) goto fail;
- func_t f = dlsym(handle, "f");
- if (!f) goto fail;
- return f;
-fail:
- fputs(dlerror(), stderr);
- exit(EXIT_FAILURE);
-#endif // DYNAMIC_LOAD
-}
-
-int main(int argc, char *argv[]) {
- func_t function = NULL;
- const char *out = NULL;
- char task2 = 1;
- float dx = 0.0;
- // casual argument loop
- for (int i = 1; i < argc; ++i) {
- if (!strcmp(argv[i], "-h"))
- print_help(EXIT_SUCCESS);
- else if (!strcmp(argv[i], "-f"))
- function = get_function(argv[++i]);
- else if (!strcmp(argv[i], "-o"))
- out = argv[++i];
- else if (!strcmp(argv[i], "-d"))
- task2 = 0;
- else if (!strcmp(argv[i], "-x"))
- dx = atof(argv[++i]);
- else print_help(EXIT_FAILURE);
- }
- // if function or output file is not set, or if dx is not set for task3,
- // then exit with failure
- if ((!function || !out) || (!task2 && dx == 0.0))
- print_help(EXIT_FAILURE);
-
- long table_len;
- struct dval *table = NULL;
- if (task2)
- table = get_table(function, 0, 3, 0.01, &table_len);
- else // task 3
- table = differentiate(function, -3, 3, dx, &table_len);
-
- // print data to stdout and to file
- print_table(stdout, table, table_len);
- FILE *f = fopen(out, "w+");
- if (f) print_table(f, table, table_len);
- else perror(out);
-
-#ifdef PIPE_GNUPLOT
- pipe_gnuplot(table, table_len);
-#endif // PIPE_GNUPLOT
-
- fclose(f);
- free(table);
-#ifdef DYNAMIC_LOAD
- if (handle) dlclose(handle);
-#endif // DYNAMIC_LOAD
- exit(EXIT_SUCCESS);
-}
-
diff --git a/src/integral.c b/src/integral.c
new file mode 100644
index 0000000..d2ae11f
--- /dev/null
+++ b/src/integral.c
@@ -0,0 +1,38 @@
+#include "integral.h"
+
+// эта переменная позволяет контролировать точность интегрирования
+// и может быть установлена в файле main
+double accrc = 10000.0;
+
+// интеграл прямоугольниками
+double int_rect(f_t f, double a, double b) {
+ // f(x + dx/2) * dx
+ const double dx = (b-a) / accrc;
+ const double dx_2 = dx / 2.0;
+ double sum = 0.0;
+ for (double i = a + dx; i < b; i += dx)
+ sum += f(i - dx_2) * dx;
+ return sum;
+}
+
+// интеграл трапециями
+double int_trap(f_t f, double a, double b) {
+ // ( f(x) + f(x+dx) )/2 * dx
+ const double dx = (b-a) / accrc;
+ double sum = 0.0;
+ for (double i = a; i < b; i += dx)
+ sum += dx * (f(i) + f(i+dx))/2 ;
+ return sum;
+}
+
+// интегрирование параболами
+double int_simp(f_t f, double a, double b) {
+ const double dx = (b-a) / accrc;
+ const double dx_2 = dx / 2;
+ const double dx_6 = dx / 6;
+ double sum = 0.0;
+ for(double i = a; i < b; i += dx) {
+ sum += dx_6 * (f(i) + 4 * f(i + dx_2) + f(i + dx));
+ }
+ return sum;
+}
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..c3844f0
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,99 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <unistd.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <dlfcn.h>
+
+#include "integral.h"
+#include "roots.h"
+
+#define BLINK_TERM "\x1b[5m"
+#define RESET_TERM "\x1b[0m"
+#define FIFO_NAME "/tmp/compiler.fifo"
+#define SYMNAME "f"
+#define RDCHUNK 1024
+
+void *sohandle;
+
+// This will be the type of the function
+typedef double(*f_t)(double);
+
+enum optype {
+ // решение уравнений
+ SOL_BINSR, // дихтомии
+ SOL_HORDE, // хорды
+ SOL_NEWTN, // касательные
+ SOL_ITERN, // итерации
+ // численное интегрирование
+ INT_RECT, // прямоугольники
+ INT_TRAP, // трапеции
+ INT_SIMP, // симпсон
+};
+
+// Function that reads Your function, compiles and loads it.
+f_t input_and_compile(void) {
+ puts("Напечатайте функцию от x используя синтаксис С и функции библиотеки cmath: \n"
+ "(например, 'atan(x) / (1-exp(2*x))').\n"
+ "Закончите ввод, нажав enter." BLINK_TERM);
+
+ // input the function
+ size_t blen = 1024;
+ char *buffer = malloc(sizeof (char) * blen);
+ blen = read(STDIN_FILENO, buffer, 1024);
+ buffer[--blen] = '\0';
+ if (blen <= 0) return NULL;
+
+ // format the source
+ const char *fmt =
+ "#include <math.h>\n"
+ "double " SYMNAME "(double x) { return %s; }\n";
+ size_t sourcelen = strlen(fmt) - strlen("%s") + blen + 1;
+ char *source = malloc(sizeof (char) * sourcelen);
+ snprintf(source, sourcelen, fmt, buffer);
+
+ // spawn the compiler process
+ FILE *cc = popen("cc -shared -fPIE -fPIC -o " FIFO_NAME " -xc - -lm", "w");
+ fwrite(source, sizeof (char), sourcelen - 1, cc);
+ fflush(cc);
+ if (ferror(cc)) return NULL;
+ if (pclose(cc) != 0) return NULL;
+
+ // load dynamic library
+ sohandle = dlopen(FIFO_NAME, RTLD_NOW);
+ if (!sohandle) return NULL;
+ f_t ret = dlsym(sohandle, SYMNAME);
+
+ // free resources and return
+ free(buffer);
+ free(source);
+ return ret;
+}
+
+// Prompts user to choose input method
+enum optype get_optype(void) {
+ return INT_SIMP;
+}
+
+int main(int argc, char *argv[]) {
+ (void)argc; (void)argv;
+ f_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);
+
+exit:
+ dlclose(sohandle);
+ return 0;
+}
diff --git a/src/roots.c b/src/roots.c
new file mode 100644
index 0000000..0aef762
--- /dev/null
+++ b/src/roots.c
@@ -0,0 +1,94 @@
+#include "roots.h"
+#include <math.h>
+#include <stdio.h>
+
+char root_ok = 1;
+
+// функция для проверки того, успешно ли выполнилась последняя функция
+char is_root_ok(void) {
+ return root_ok;
+}
+
+// метод дихтомии
+double sol_binsr(f_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;
+ }
+
+ double mid;
+ do {
+ mid = (a + b) / 2;
+ if (copysign(1.0, f(a)) != copysign(1.0, f(mid))) b = mid;
+ else a = mid;
+ } while (f(mid) > ey || (b-a) > ex);
+ root_ok = 1;
+ return mid;
+}
+
+// метод хорд
+double sol_chord(f_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;
+ }
+ double mid = a + fabs( f(a) / (f(b)-f(a)) ) * (b-a);
+ double diff = mid;
+ while (f(mid) > ey || fabs(diff - mid) > ex) {
+ diff = mid;
+ mid = a + fabs( f(a) / (f(b)-f(a)) ) * (b-a);
+ if (copysign(1.0, f(a)) != copysign(1.0, f(mid))) b = mid;
+ else a = mid;
+ }
+ root_ok = 1;
+ return mid;
+
+}
+
+// метод касательных (Ньютона)
+double sol_newtn(f_t f, double x0, double ex, double ey) {
+ const double dx = 1e-6;
+ double diff = x0+2*ex;
+
+ // check for divergence
+ double d2x0 = (f(x0 + 2*dx) - 2*f(x0 + dx) + f(x0))/(dx*dx);
+ if (copysign(1.0, d2x0) != copysign(1.0, f(x0))) {
+ root_ok = 0;
+ return NAN;
+ }
+ while ((fabs(diff - x0) > ex || f(x0) > ey)) {
+ double fx0 = f(x0);
+ double dx0 = (f(x0+dx) - fx0) / dx;
+ diff = x0;
+ x0 -= fx0/dx0;
+ if (isinf(x0) || isnan(x0)) {
+ root_ok = 0;
+ return NAN;
+ }
+ }
+ root_ok = 1;
+ return x0;
+}
+
+// метод итераций
+double sol_itern(f_t f, double x0, double ex, double ey) {
+ const double dx = 1e-6;
+ double diff = x0 + 2*ex;
+
+ do {
+ double dx0 = (f(x0+dx) - f(x0))/dx;
+ if (fabs(dx0) > 1.0) {
+ root_ok = 0;
+ return NAN;
+ }
+ diff = x0;
+ x0 = f(x0);
+ printf("x0=%lf, f(x0)=%lf\n", x0, f(x0));
+ getchar();
+ } while (fabs(diff - x0) > ex || fabs(f(x0) - x0) > ey);
+ root_ok = 1;
+ return x0;
+}
+
+
+
diff --git a/test_f.c b/test_f.c
deleted file mode 100644
index 8811f1e..0000000
--- a/test_f.c
+++ /dev/null
@@ -1,5 +0,0 @@
-double f(double x) {
- static int counter = 0;
- ++counter;
- return counter * x;
-}