Загрузка данных
#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;
}