Условие
Условие задачи
Вычислите с точностью [latex]\varepsilon[/latex] значение функции [latex]f(x)=\arcsin x[/latex].
При вычислениях допустимо использовать только арифметические операции.
Тесты
№ | [latex] x [/latex] | [latex] arcsin x [/latex] |
1 | -1 | -1.56709 |
2 | -0.5 | -0.523599 |
3 | 0 | 0 |
4 | 0.5 | 0.523599 |
5 | 0.7071067 | 0.785398 |
6 | 0.8660254 | 1.0472 |
Решение
Чтобы разложить тригонометрическую функцию только арифметическими операциями, нужно воспользоваться формулами Тейлора.
Ряд Тейлора для функции [latex]\arcsin x[/latex]:
[latex]\arcsin x = \sum_{n=0}^{\infty} \frac{(2n)!}{4^n (n!)^2 (2n+1)} x^{2n+1}[/latex]
или:
[latex]\arcsin x = x + \frac{x^3}{6} + \frac{3x^5}{40} + \cdots[/latex]
Вводим переменную, которая будет считать арксинус — [latex]arcsin[/latex].
Так как первый член — [latex]x[/latex], то начальное значение [latex]\arcsin =x[/latex] и [latex]a=x[/latex]. [latex]a[/latex] — это слагаемые суммы, оно будет изменятся с каждым последующим значением [latex]n[/latex].
Теперь нужно узнать на сколько домножать первое слагаемое из ряда Тейлора, чтобы получить второе:
[latex]\frac{(2(n+1))!\cdot x^{2(n+1)+1}}{4^{n+1}((n+1)!)^2 (2(n+1)+1)} \cdot \frac{4^n (n!)^2 (2n+1)}{(2n)!\cdot x^{2n+1}} = \frac{(2n+1)^2 x^2}{2(2n+3)(n+1)}[/latex]Видно, что эта функция сначала возрастает, а потом убывает ( [latex]x\leq 1[/latex] )
[latex]\frac{(2n+1)^2 x^2}{2(2n+3)(n+1)}[/latex], поэтому [latex]a[/latex] будет уменьшаться. Мы задаем точность [latex]\varepsilon[/latex] и пока [latex]a > \varepsilon[/latex] мы вычисляем сумму
[latex]\arcsin +=a[/latex].
Код
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <cmath> using namespace std; int main() { int n=0; double x; cin >> x; double a=x, arcsin=x, E=0.1e-5; while (abs(a*=(x*x*(2*n+1)*(2*n+1)/(2*(n+1)*(2*n+3))))>E) { arcsin+=a; n++; } cout << arcsin; return 0; } |
Почему все так не любят \varepsilon в LaTeX, а используют \in?
Простите, я немного перепутал. Но лучше использовать \varepsilon чем просто \epsilon.
В самом задании написано \epsilon и я решила не менять, но, если нужно, то поменяю.
Филип прав. В условиях я исправил.
Кстати, в условии \arcsin х, а Вы ограничились arcsin х.
не удивительно, что перепутал. Они очень похожи [latex]\in \epsilon[/latex]. Но Вы правы — [latex]\varepsilon[/latex] больше соответствует нашей традиции.
— Вы пишите «присваиваем начальное значение [latex]\arcsin x =x[/latex]». Я понимаю, что Вы хотите сказать, но так писать нельзя. И так [latex]\arcsin x+=a[/latex] тоже. Конечно, в программе можно переменную назвать arcsin, но это не то, что Вы пишите в пояснительном тексте.
— У знака сумму забыли указать бесконечность в качестве верхнего предела.
— Вы пишите то очередное «слагаемое», то просто «число». Слагаемое лучше. Чисел-то у Вас много, не ясно о чём идёт речь.
— Вы пишите «мы выполняем сумму». Существительное «сумма» не сочетается с глаголом «выполнять». Выполняют команду, а сумму вычисляют. Т.е. одно из слов нужно заменить.
— Этот фрагмент Вашего кода нуждается в исправлении:
Основная ошибка в условии окончания цикла. Операция *= выполняется последней. Т.е. не хватает скобок. Кроме того, в сравнении должен участвовать модуль очередного слагаемого. Если в while всё сделать аккуратно, то следующая строка уже не понадобится. Конечно, можно вторую строку оставить, но тогда в условии проверять просто модуль а.
Всё исправила.
Возможно я не очень понятно написал в конце прошлого комментария. Не нужно вычислять одно и то же два раза в 8-й и 9-й строке.
Исправила. Так лучше?
Лучше.
Последнее замечание. Для вставки в строку описания фрагмента кода программы нужно пользоваться тегом code (в угловых скобках). Получается так arcsin += a. Вы вставляете фрагменты программы как математические формулы при помощи latex. Это неправильно.
Зачтено. Молодец.
Хотя задачка-то за октябрь…