Загрузка данных


#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <stdio.h>
#include <math.h>
#include <windows.h>

/* Рядная функция f(x) по варианту 10:
   tg(pi*x/2) = (4x/pi) * sum_{n=1..inf} 1 / ((2n-1)^2 - x^2)

   series_f:
   - x: аргумент
   - eps: точность
   - *terms: возвращает количество членов ряда
   - *ok: 1 = всё хорошо; 0 = ошибка (деление на ноль, не сошлось и т.п.)
   Возвращает частичную сумму S.
*/
double series_f(double x, double eps, int* terms, int* ok)
{
    const int MAX_TERMS = 1000000;
    *ok = 1;
    *terms = 0;

    /* Проверка на особые точки x ≈ 1+2k (разрывы tan(pi*x/2)) */
    double k_nearest = round((x - 1.0) / 2.0);   /* ближайшее k: x ≈ 1+2k */
    if (fabs(x - (1.0 + 2.0 * k_nearest)) < 1e-8) {
        *ok = 0;
        return NAN;
    }

    /* первый член ряда a1 */
    double denom1 = 1.0 - x * x; /* (2*1 -1)^2 - x^2 = 1 - x^2 */
    if (fabs(denom1) < 1e-14) {
        *ok = 0;
        return NAN;
    }

    double a = (4.0 * x / M_PI) / denom1; /* a1 */
    double s = a;
    *terms = 1;

    while (fabs(a) >= eps && *terms < MAX_TERMS) {
        int n = *terms + 1; /* следующий n */

        double num = (2.0 * n - 3.0);
        num = num * num - x * x;      /* (2n-3)^2 - x^2 */
        double den = (2.0 * n - 1.0);
        den = den * den - x * x;      /* (2n-1)^2 - x^2 */

        if (fabs(den) < 1e-14) {
            *ok = 0;
            return s; /* до этого была нормальная сумма */
        }

        double k = num / den;
        a = a * k;
        s += a;
        (*terms)++;
    }

    if (*terms >= MAX_TERMS) {
        *ok = 0; /* не сошлось за разумное количество шагов */
    }

    return s;
}

/* Библиотечная функция: F(x) = tg(pi * x / 2) */
double F_lib(double x, int* ok)
{
    double val = tan(M_PI * x / 2.0);
    if (!isfinite(val)) {
        *ok = 0;
        return NAN;
    }
    *ok = 1;
    return val;
}

/* Невязка δ = sqrt(|f^2 - F^2|) */
double delta(double f, double F)
{
    return sqrt(fabs(f * f - F * F));
}

int main(void)
{
    /* Включаем UTF‑8 в консоли, чтобы русский текст отображался нормально */
    SetConsoleOutputCP(65001);
    SetConsoleCP(65001);

    double eps;                /* точность для первой таблицы */
    double x_start, x_end, dx; /* диапазон x */
    double x_ideal;            /* точка для второй таблицы */

    printf("Лабораторная работа 4. Вариант 10.\n");
    printf("Ряд для tg(pi*x/2).\n\n");

    printf("Введите точность eps (для таблицы 1): ");
    if (scanf("%lf", &eps) != 1) {
        printf("Ошибка ввода eps.\n");
        return 1;
    }

    printf("Введите x_start, x_end и шаг dx: ");
    if (scanf("%lf %lf %lf", &x_start, &x_end, &dx) != 3) {
        printf("Ошибка ввода диапазона x.\n");
        return 1;
    }

    printf("Введите x_ideal (для таблицы 2): ");
    if (scanf("%lf", &x_ideal) != 1) {
        printf("Ошибка ввода x_ideal.\n");
        return 1;
    }

    /* ---------------- Таблица 1 ---------------- */
    printf("\nТаблица 1. Значения на отрезке [%g; %g] с шагом %g, eps = %g\n",
           x_start, x_end, dx, eps);
    printf("--------------------------------------------------------------------------------\n");
    printf("| %10s | %15s | %15s | %15s | %7s |\n",
           "x", "f(x) (ряд)", "F(x) (tg)", "delta", "terms");
    printf("--------------------------------------------------------------------------------\n");

    /* считаем количество шагов, чтобы не было проблемы с double-шагом */
    int nSteps = 0;
    if (dx != 0.0) {
        nSteps = (int)floor((x_end - x_start) / dx + 0.5);
    }

    for (int i = 0; i <= nSteps; ++i) {
        double x = x_start + dx * i;

        int ok_f, ok_F;
        int terms;
        double f = series_f(x, eps, &terms, &ok_f);
        double F = F_lib(x, &ok_F);

        if (!ok_f || !ok_F) {
            printf("| %10.4f | %15s | %15s | %15s | %7s |\n",
                   x, "error", "error", "error", "-");
        } else {
            double d = delta(f, F);
            printf("| %10.4f | %15.8f | %15.8f | %15.8e | %7d |\n",
                   x, f, F, d, terms);
        }
    }
    printf("--------------------------------------------------------------------------------\n");

    /* ---------------- Таблица 2 ---------------- */
    printf("\nТаблица 2. Значения в точке x = %g для различных eps\n", x_ideal);
    printf("--------------------------------------------------------------------------------\n");
    printf("| %10s | %15s | %15s | %15s | %7s |\n",
           "eps", "f(x)", "F(x)", "delta", "terms");
    printf("--------------------------------------------------------------------------------\n");

    double eps_values[] = {1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7};
    int n_eps = sizeof(eps_values) / sizeof(eps_values[0]);

    for (int i = 0; i < n_eps; ++i) {
        double e = eps_values[i];
        int ok_f, ok_F, terms;
        double f = series_f(x_ideal, e, &terms, &ok_f);
        double F = F_lib(x_ideal, &ok_F);

        if (!ok_f || !ok_F) {
            printf("| %10.1e | %15s | %15s | %15s | %7s |\n",
                   e, "error", "error", "error", "-");
        } else {
            double d = delta(f, F);
            printf("| %10.1e | %15.8f | %15.8f | %15.8e | %7d |\n",
                   e, f, F, d, terms);
        }
    }

    printf("--------------------------------------------------------------------------------\n");

    printf("\nНажмите Enter для выхода...\n");
    getchar(); /* съесть '\n' после последнего scanf */
    getchar(); /* ожидание Enter */

    return 0;
}