Почему значения косинуса неправильны?
Необходимо найти значения косинуса с помощью ряда Тейлора:
Количество итераций задаёт пользователь. Вот реализация:
#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 шт):
Повторюсь.
А чему равно 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].
Стандартная формула ряда Тейлора является академической, и всегда даёт результат с ошибкой в младших знаках. Ошибка проявляется вследствие превышения диапазона вычислений за пределы возможностей выбранного формата чисел. Количество итераций ограничено, складывать ноль не имеет смысла. Второй тип накопления ошибки связан с потерей точности при сложении чисел с разной степенью. Надо сначала сохранить результаты вычислений цикла, а после сложить в обратном порядке. Третий тип ошибки накопительный - следствие выбранного количества интеграций. Лучшие результаты можно получить в диапазоне -π/4, +π/4, с комбинацией sin cos, и смещением входного значения до нуля.
Для ускорения вычислений используют таблицы - результат исключения медленной операции деления. https://github.com/AVI-crak/Rtos_cortex/blob/master/math_s.h