Возникли проблемы при вычислении суммы бесконечного ряда

117
30 августа 2021, 08:20

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

#include <iostream>
#include <iomanip>
#include <cmath>
#define M_PI_4
using namespace std;
int fact(int n)
{
    if (n == 0) {
        return 1;
    }
    else if (n == 1)
    {
        return 1;
    }
    return n * (n - 1);
}

int main()
{
    setlocale(LC_ALL, "ru");
    double e = 10;
    e = pow(e, -4); // Заданная точность
    int n = 1;
    double x,
        m = 1,
        y = sqrt(2) / 2, //pi / 4 = sqrt(2)/2
        res = m;
    printf("Введите x (0.1 <= x <= 1): ");
    cin >> x;
    while (x > 1 || x < 0.1) {
        printf("Введено неверно значение x, попробуйте ещё раз (0.1 <= x <= 1): ");
        cin >> x;
    }
    while (m > e)
    {
        m *= cos(y)*x / fact(n);
        res += m;
        n++;
    }
    double check = exp(x * cos(y)) * cos(x * sin(y));
    cout << setprecision(5) << "Результат бесконечного ряда, в котором x = " << x << ": " << res << endl;
    cout << setprecision(5) << check << endl << res << " = " << check << endl;
    system("pause");
    return 0;
}

Значение pi/4 я записал в численном виде (√‎2/2), т.к. при вычислении синуса или косинуса из этого числа все время выдавало ошибку (я записывал ,к примеру, cos(M_PI_4) и выходила ошибка "Отсутствуют экземпляры. Перегруженная функция "cos", соответствующие списку аргументов").

Я все-таки думаю, что само вычисление бесконечного ряда у меня выполнено неверно, однако не могу понять, что я сделал не так)

Answer 1

Вам не нужно считать факториал отдельно, не нужно задавать 10-4 как pow(10,-4), когда есть литерал 1e-4, на худой конец 0.0001, нужно считать cos(n*pi/4), а не cos(pi/4), нужно... много нужно. Все вместе дает вот такой код:

const double pi = 3.1415926;
double summa(double x, double eps = 1e-7) {
    double sum = 1, term = 1;
    for (int n = 1; abs(term) > eps; ++n)
        sum  = sum + (term *= x/n)*cos(n * pi / 4);
    return sum;
}
int main() {
    for (double x = 0.1; x < 1.05; x += 0.1) {
        cout
            << setprecision(3) << left << setw(4) << x
            << setprecision(7) << left << setw(10) << summa(x)
            << setprecision(7) << left << setw(10)
            << exp(x * cos(pi / 4))*cos(x * sin(pi / 4)) << endl;
    }
}

Кстати, вычисление cos(n*pi/4) действительно можно ускорить (но не упростить), примерно как

double NCos(int n)
{
    static const double s2 = 1/sqrt(2);
    double res = (n%2 == 1) ? s2 : (n%4 == 0) ? 1 : 0;
    if (n%8 >= 3 && n%8 <= 5) res *= -1;
    return res;
}

(http://ideone.com/Ty4E3h)

READ ALSO
Как добавить программу в автозагрузку используя WinAPI (C/C++)

Как добавить программу в автозагрузку используя WinAPI (C/C++)

Какая функция, описание которой находится в заголовочном файле windowsh (насколько я знаю, она там), отвечает за автозапуск и как прописать, заранее...

129
как поставить картинке position: sticky;?

как поставить картинке position: sticky;?

Есть код, и надо к картинкам добавить position: sticky;, возможно ли это сделать? У меня лично не получается

131
Как правильно реализовать Lazy-loading для &lt;picture /&gt;

Как правильно реализовать Lazy-loading для <picture />

Использую тэг <picture /> для реализации fallback-механизма для WebP-изображений:

90
Автономный таймер 60 дней

Автономный таймер 60 дней

Как можно реализовать таймер на 60 дней, который начнет работать с момента создания, не зависимо, видел ли его посетитель?

85