Почему неправильно работает программа, рекуррентно высчитывающая значение синуса через ряд Тейлора?

Условие задачи:"Необходимо написать программу, в которой вводятся значения n и x и выводится сумма ряда с указанной точностью n, а также сумма ряда с максимально возможной точностью" Например, для значения x = 32.2 не выводится заданная точность, а максимальная печатается. Может быть есть ошибки, которые я не могу увидеть? Объясните, пожалуйста. Заранее благодарен!

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

// Определение значения эпсилон
#define LDBL_EPSILON pow(2,-63)

// Функция для вычисления максимально возможной точности через эпсилон
int max_accuracy(long double x, long double n, long double e)
{
    int i;
    long double memory = x;
    for (i = 0; i < n; i++)
    {
        memory *= -x * x / ((2 * i + 2) * (2 * i + 3));
        // Проверяем условие окончания итераций
        if (fabsl(memory) <= e)
        {
            break;
        }
    }
    return i;
}

long double max_sum(long double x, long double n, long double e)
{
    int i;
    long double sum_i = x;
    long double memory = x;
    for (i = 0; i < n; i++)
    {
        memory *= -x * x / ((2 * i + 2) * (2 * i + 3));
        sum_i += memory;
        // Проверяем условие окончания итераций
        if (fabsl(memory) <= e)
        {
            break;
        }
    }
    return sum_i;
}

int main()
{
    long double n, x, sum, term = 0;
    printf("input n:");
    scanf_s("%Lf", &n);
    printf("input x:");
    scanf_s("%Lf", &x);
    // Определение значения эпсилон
    long double e = LDBL_EPSILON;
    int maxN = max_accuracy(x, n, e); // Вычисление максимально возможной точности
    // Итерации для вычисления синуса с помощью формулы Тейлора
    sum = x;
    long double member = x;
    for (int i = 0; i <= maxN; i++) {
        member *= (-x * x / ((2 * i + 2) * (2 * i + 3)));
        sum += member;
        if (i == n) {
            printf("given accuracy: %.15lf\n", sum);
        }
    }
    printf("sin max accuracy: %.15lf\n", max_sum(x,n,e));
    printf("sin math.h: %.15lf", sinl(x));
    return 0;
}

 

Ответы (2 шт):

Автор решения: AlexGlebe

При создании функции int max_accuracy(long double x, long double n, long double e) вы скопировали код из другой long double max_sum(long double x, long double n, long double e) и совершили типичную ошибку бездумного копирования кода.
Цикл должен заканчиваться до условия, приближения к заданной точности, а не количеству слагаемых.
Нужно удалить лишний аргумент n.

int max_accuracy(long double x, /* long double n,*/ long double e)
{
    int i;
    long double memory = x;
    for (i = 0; /*i < n*/ ; i++)
    {
        memory *= -x * x / ((2 * i + 2) * (2 * i + 3));
        // Проверяем условие окончания итераций
        if (fabsl(memory) <= e)
        {
            break;
        }
    }
    return i;
}

И попутно нужно исправить в функциях printf заменой "%lf" на "%Lf"

→ Ссылка
Автор решения: AVI-crak Home

В справочниках форумы Тейлора представлены в математическом виде, это когда количество цифр после запятой бесконечно. Но в реальности переменные имеют фиксированную точность. Для того чтобы не накапливать ошибку, нужно складывать от меньшего к большему. Буквально сохранять результаты в массив, и только потом вычислять сумму. Кроме того есть минимальный порог для входного параметра, ниже нельзя - получится бесконечность.

→ Ссылка