Почему значения косинуса неправильны?

Необходимо найти значения косинуса с помощью ряда Тейлора:

введите сюда описание изображения

Количество итераций задаёт пользователь. Вот реализация:

#include <stdlib.h>
#include <math.h>

int isCorrect(float actual, float target){
    if (actual == target) return 1;
    else return 0;
}
int Phactorial(int n){
    int fact = 1;
    for (int i = 1; i <= n; i++)
        fact *= i;
    return fact;
}

int main() {
    system("chcp 1251");
    double z;
    int countIteration, countCorrectInput;
    float result = 0;
    printf("Приветствуем вас в программе подсчёта\n"
           "cos(z) по итерационной формуле!\n"
           "Введите через пробел z и точность (кол-во итераций):\n");
    countCorrectInput = scanf("%lf%d", &z, &countIteration);
    if (isCorrect(countCorrectInput, 2)){
        for (int i = 0; i <= countIteration; i++){
            result += pow(-1, i) *
                    pow(z, 2*i) / Phactorial(2*i);
        }
        printf("cos(z) = %f", result);
    }
    else{
        printf("Введены некорректные значения");
    }
    return 0;
}

Если количество итераций меньше 7, то программа считает всё правильно, однако после она выдаёт невозможные значения. Помогите решить проблему


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

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

Повторюсь.

А чему равно 14!, вы не задумывались? Помещается ли оно в int? Кстати, количество итераций - не есть точность, точность - это значение последнего члена ряда, что для знакопеременных сходящихся рядов есть непреложная истина :)

Нашлась минутка, вот код функции, которая вычисляет косинус с помощью ряда, с заданной точностью, и в которой ну совершенно не нужны ни две функции pow, ни вычисление факториала.

double Cos(double x, double eps)
{
    x *= x;
    double sum = 1, term = 1;
    for(int n = 1; abs(term) > eps; n+=2)
        sum += term *= -x/n/(n+1);
    return sum;
}

Для больших значений x лучше не использовать их непосредственно, а исходя из периодичности приводить к диапазону поменьше, скажем, [-π/2, +π/2].

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

Стандартная формула ряда Тейлора является академической, и всегда даёт результат с ошибкой в младших знаках. Ошибка проявляется вследствие превышения диапазона вычислений за пределы возможностей выбранного формата чисел. Количество итераций ограничено, складывать ноль не имеет смысла. Второй тип накопления ошибки связан с потерей точности при сложении чисел с разной степенью. Надо сначала сохранить результаты вычислений цикла, а после сложить в обратном порядке. Третий тип ошибки накопительный - следствие выбранного количества интеграций. Лучшие результаты можно получить в диапазоне -π/4, +π/4, с комбинацией sin cos, и смещением входного значения до нуля.

Для ускорения вычислений используют таблицы - результат исключения медленной операции деления. https://github.com/AVI-crak/Rtos_cortex/blob/master/math_s.h

→ Ссылка