Задача
Вычислите с точностью значение функции
. При вычислениях допустимо использовать только арифметические операции.
Решение
Функцию [latex]f(x)=\tan x [/latex] можно представить в виде: [latex]f(x)=\frac{\sin x}{\cos x}[/latex] (по свойствам тангенса). Поэтому будем раскладывать в ряд две функции: [latex]\sin x[/latex] и [latex]\cos x[/latex].
Для решения задачи необходимо воспользоваться формулой Тейлора с опорной точкой (ряд Маклорена). Для функции [latex]f(x)=\sin x[/latex] она имеет следующий вид:
А для [latex]f(x)=\cos x[/latex]:
[latex]f(x)=1-\frac{x^{2}}{2!}+\frac{x^{4}}{4!}-\cdots=\sum_{n=0}^{\infty}(-1)^{n}\frac{x^{2n}}{(2n)!}[/latex]Далее нам нужно найти рекуррентные формулы для членов данных рядов.
[latex]\frac{a_n}{a_n-_1}=\frac{-x^{2}}{(2n+2)(2n+3)}[/latex]; [latex]\frac{b_n}{b_n-_1}=\frac{-x^{2}}{(2n+1)(2n+2)}[/latex]При помощи функции fmod удалим период, так как тангенс [latex]\pi[/latex] периодичная функция.
Затем необходимо накапливать сумму текущих членов ряда для синуса и косинуса соответственно до тех пор, пока слагаемое не будет меньше заданной точности.
Код
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> #include <cmath> using namespace std; double tangent(double x, double accuracy) { int i = 1; double cos = 1, sin = x, intermediateValueCos = 1, intermediateValueSin = x; x = fmod(x, M_PI); while (fabs(intermediateValueCos *= - x * x / (2 * i * (2 * i - 1))) > accuracy && fabs(intermediateValueSin *= - x * x / (2 * i * (2 * i + 1))) > accuracy) { cos += intermediateValueCos; sin += intermediateValueSin; i++; } return sin / cos; } int main() { double x, accuracy; cin >> x >> accuracy; cout << tangent(x, accuracy); return 0; } |
Тесты
Входные данные | Выходные данные |
0.42 0.001 | 0.446569 |
1.52 0.001 | 19.9377 |
3.1415 0.0001 | -0.000113798 |
Задача взята отсюда.
Код программы на Ideone.com.
Вас смутили числа Бернулли в разложении тангенса? Там совсем не так сложно, как может показаться на первый взгляд. Решение через синус и косинус получить вроде проще, но всплывает много мелких камушков, о которые можно споткнуться.
— Вы пишите «нам нужно найти рекуррентную форму для членов данного ряда». Но никакого ряда у Вас нет! У Вас частное. В числителе и знаменателе — суммы рядов. К счастью они сходятся и всё будет хорошо. Но частное это не ряд и общего члена у него соответственно нет.
— Я даже не рискую предположить, какие ужасные ошибки скрываются за этой записью [latex]\frac{a_n}{b_n}=\frac{\frac{-x^{2}}{(2n+1)(2n+2)}}{\frac{-x^{2}}{(2n+2)(2n+3)}}[/latex] и что Вы при этом думали 🙂 Если увидит кто-то с кафедры матанализа…
— Программа отнюдь не так безумна, как пояснения. Думаю, она бы меня вполне устроила. Жаль Вы так затянули с публикацией.
Что нужно будет переделать? Нужно откровенно написать, что тангенс Вы в ряд раскладывать не будете. Вместо этого разложите в ряд синус и косинус. Для членов каждого из рядов Вы совершенно верно нашли отношение предыдущего к последующему. Только не нужно смешивать эти ряды. И запишите правильно обе найденные рекуррентные формулы.
Игорь Евгеньевич, исправила. Проверьте, пожалуйста.
Принято.
Но всё таки прямое вычисление суммы ряда для тангенса мне бы больше понравилось.