1)
Код:
#include <stdio.h> #include <stdlib.h> #include <math.h> enum { A12 = 18, B12 = 30, A13 = -10, B13 = 0, A23 = 0, B23 = 10, EPS = 1000 }; typedef double (*func)(double); double f1(double x); double f2(double x); double f3(double x); double deriv(func f, double x, double dx); double root(func, func, double, double, double); double integral(func, double, double, double); int main(void) { //printf("----------\nDEBUG:\n----------\n"); double eps1 = 0.1 / EPS, eps2 = 0.01 / EPS; double a = root(f1, f2, A12 / 10.0, B12 / 10.0, eps1); double b = root(f1, f3, A13 / 10.0, B13 / 10.0, eps1); double c = root(f2, f3, A23 / 10.0, B23 / 10.0, eps1); double i1, i2, i3; if(a < b) i1 = integral(f1, a, b, eps2); else i1 = integral(f1, b, a, eps2); //printf("i1 - %lf\n", i1); if(a < c) i2 = integral(f2, a, c, eps2); else i2 = integral(f2, c, a, eps2); //printf("i2 - %lf\n", i2); if(b < c) i3 = integral(f3, b, c, eps2); else i3 = integral(f3, c, b, eps2); //printf("i3 - %lf\n", i3); double I = i1 - i2 - i3; //printf("%lf\n", I); //printf("----------\nSTOP DEBUG\n----------\n"); printf("f1(x) = 3/((x - 1) * (x - 1) + 1)\nf2(x) = sqrt(x + 0.5)\nf3(x) = exp(-x)\n"); printf("Points of intersection:\n"); printf(" f1 and f2: %.5lf\n", a); printf(" f1 and f3: %.5lf\n", b); printf(" f2 and f3: %.5lf\n", c); printf("Area: %.5lf\n", I); return 0; } double f1(double x) { return 3/((x - 1) * (x - 1) + 1); } double f2(double x) { return sqrt(x + 0.5); } double f3(double x) { return exp(-x); } double deriv(func f, double x, double dx) { double dy = (*f)(x + dx) - (*f)(x); return dy / dx; } // комбинированный способ double root(func f, func g, double a, double b, double eps) { char sgnd1 = ((*f)(a) - (*g)(a)) < 0; // знак первой производной F(x) = f(x) - g(x) char sgnd2f = (*f)((a + b) / 2) <= (((*f)(a) + (*f)(b)) / 2); char sgnd2g = (*g)((a + b) / 2) <= (((*g)(a) + (*g)(b)) / 2); char sgnd2 = sgnd2f * sgnd2g; // знак второй производной F(x) char sgn = !(sgnd1 ^ sgnd2); // F'(x) * F''(x) > 0 double c1, c2, Fa, Fb; while(b - a >= eps){ Fa = (*f)(a) - (*g)(a); Fb = (*f)(b) - (*g)(b); c1 = (a * Fb - b * Fa) / (Fb - Fa); // точка пересечения хорды с осью абсцисс if(sgn) c2 = b - Fb / (deriv(f, b, eps) - deriv(g, b, eps)); else c2 = a - Fa / (deriv(f, a, eps) - deriv(g, a, eps)); if(c2 > c1){ b = c2; a = c1; } else { b = c1; a = c2; } } return (a + b) / 2; } // метод прямоугольников double integral(func f, double a, double b, double eps) { int n = 1 / eps; double p = 1 / 3.0; double h; double Fi; double In = 0, I2n = 0; int i; do{ In = I2n; n *= 2; h = (b - a) / n; for(i = 0; i < n; i++){ Fi = (*f)(a + (i + 0.5) * h); I2n += Fi; } I2n *= h; }while(p * abs(In - I2n) >= eps); return I2n; }