Вычислите значение coshx, используя индивидуальные ряды в cpp - PullRequest
0 голосов
/ 09 мая 2018

Мне было поручено вычислить значение coshx, используя индивидуальные ряды в CPP. Я попробовал простой подход с использованием факториала и степенной функции, но я заметил, что при больших значениях х факториал ведет себя резко и дает очень отклоняющиеся значения вот мой код

#include <iostream>

using namespace std;
long double fact(int);
int main()
{
    long double a;
    long double sum = 0;
    cout << "Enter value of x " << endl;
    cin >> a;
    for (long c = 2; c <= 12; c++)
    {
        if (c % 2 == 0)
        {
            sum = sum + (pow(a, c) / fact(c));
            if (sum < 0)
            {
                sum=sum*-1;
            }
        }
        else
            continue;
    }
    cout << "The answer is " << 1 + sum << endl;
    system("pause");
    return 0;
}
long double fact(int x)
{
    int n = 1, fact;
    for (n; n <= x; n++)
    {
        if (n == 1)
    {
            fact = 1;
    }
        else
    {
            fact = fact * n;
    }
}
    return fact;
}

даже я использовал long double, чтобы получить максимальные биты, но это ничего не меняет, и это просто хорошо работает для меньшего количества значений (до 10) и меньшего числа циклов.

1 Ответ

0 голосов
/ 09 мая 2018

Как уже упоминалось в комментарии, вы получаете неправильные результаты из-за переполнения. Факториал особенно подвержен переполнению, потому что растет очень быстро. Дело в том, что, небрежно говоря, этот экстремальный рост и делает сходство рядов Тейлора. Если учесть полный термин, который вы добавляете на каждой итерации, он фактически идет к 0, а не к бесконечности (факториал - знаменатель).

Вместо вычисления степеней x и факториала в отдельности, вы должны просто обновлять полный термин, т.е. вместо

sum = sum + (pow(a, c) / fact(c));
             //  ^ this may grow very fast
             //           ^ this definitely grows extremely fast

вы должны сделать что-то вроде

double add = x;
double factor = 1;
while (add > eps) {    // with some appropriate value for eps
   sum += add;
   add *= (x / factor);   // <-- this will nicely converge to 0 
   factor++;
}

, как указывали другие, на самом деле это ряд Тейлора для экспоненты, но вам нужны лишь незначительные изменения, чтобы получить желаемый результат (например, пропустить нечетные).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...