Форум «Всё о Паскале» _ Задачи _ Задача о справедливости равенства!
Автор: Olchik 20.11.2007 3:37
Люди! Я написала программу на Паскале, но она как-то странно работает. Я не понимаю в каком месте ошибочка. Помогите,ПОЖАЛУЙСТА! Вот условие задачи: Численно убедиться в справедливости равенства, для чего для заданного значения аргумента х вычислить левую его часть и разложение, стоящее в правой части, с заданной погрешностью e. Оценить число итераций, необходимых для достижения заданной точности. равенство: sinx=x(1-(x*x/(pi*pi))(1-(x*x/4(pi*pi))...(1-(x*x/((n-1)*(n-1)*pi*pi)))....
Вот так вот.... Моя программа:
Program RGZ3; Uses crt; var x,Eps,a,b,y,P:real; n:integer; begin clrscr; write('Задайте значение аргумента х='); readln(x); write('Введите погрешность е='); readln(Eps); P:=x; y:=sin(x); n:=2; repeat a:=((n-1)*(n-1))*pi*pi; b:=1-((x*x)/a); n:=n+(n-1); P:=p*b; until ABS(y-p)<=Eps; if ABS(y-p)<=Eps then write('Равенство справедливо') else write('Равенство не справедливо'); readln; end.
Заранее ОГРОМНОЕ СПАСИБО!:=)
Автор: мисс_граффити 20.11.2007 5:21
Если честно, никаких странностей (кроме нарушения тобой п.2 правил) не заметила. На больших х вылетает с делением на ноль - ты про это?
Может, напишешь подробнее, в чем проблема? На каких значениях что-то не то получается? И еще меня немножко смутило
Цитата
n:=n+(n-1);
Это по формуле так? Почему не n:=n+1?
Автор: Olchik 20.11.2007 7:44
На больших х вылетает с делением на ноль - ты про это?
Да, именно про это.
Цитата
Это по формуле так? Почему не n:=n+1?
Получается ,чтобы не выходило деление на 0 необходимо первоначально задать п=2. Иначи выходит: 1-1=0, а это знаменатель....Вот...Немного бредово...но всё же.
Спасибо,что откликнулись
Автор: Sozialist 20.11.2007 9:02
Чтобы не вылетало на больших углах, нужно заменять их меньшими. Например,
repeat x:=x-2*Pi; //в силу периодичности функции until x<=2*Pi
Автор: Lapp 20.11.2007 17:06
Olchik, ты не поняла, что сказала мисс_граффити:
Цитата(мисс_граффити @ 20.11.2007 1:21)
Цитата
n:=n+(n-1);
Это по формуле так? Почему не n:=n+1?
Ты ответила:
Цитата(Olchik @ 20.11.2007 3:44)
Получается ,чтобы не выходило деление на 0 необходимо первоначально задать п=2. Иначи выходит: 1-1=0, а это знаменатель....Вот...Немного бредово...но всё же.
- что совешенно не по теме . Да, начинать нужно с n=2 при P=x, кто ж спорит? И ничего бредового в этом нет, даже немного. А вот это твое:
Цитата
n:=n+(n-1);
- это действительно полнейший бред (не немного ). Конечно, нужно писать так, как намекала мисс_граффити: n:=n+1; Это же следует из написанной тобой формулы!.. Понятно?
Цитата(Sozialist @ 20.11.2007 5:02)
Чтобы не вылетало на больших углах, нужно заменять их меньшими. ... x:=x-2*Pi; //в силу периодичности функции
Sozialist, ты не прав. Ты еще не доказал, что эта предел этой последовательности действительно синус, а уже пользуешься его, синуса, свойствами.. Нехорошо!
Olchik, задача не так проста, как кажется на первый взгляд. В ней есть несколько подводных камней, даже для знающего программиста. Я тебе сейчас немного начну намекать на них, а ты попробуй разобраться и задавай вопросы. Ладно?
1. Во-первых, надо исправить ту ошибку, про которую говорила мисс_граффити, это несомненно.
2. В процессе вычислений получаются очень большие значения. Как ты знаешь, числа, с которыми имеет дело компьютер, ограничены по величине. Например, числа типа real ограничены примерно числом 10^38, а тип double простирается до 10^308. Та последовательность, с которой ты имеешь дело, сходится чрезвычайно медленно, но дело даже не в скорости схождения. Дело в том, что она сначала колеблется с очень большой амплитудой. То есть, прежде, чем сойтись, она очень сильно отклоняется, как в плюс, так и в минус. То есть программа действительно вылетает при больших X, но не из-за ошибки, а из-за ограниченных возможностей машины. Отсюда следуют несколько выводов сразу: - для n следует использовать не integer тип, а real; - для всех действительных величин следует использовать не real тип, а double (а может, и extended); - следует организовать последовательность так, чтобы минимизировать величину промежуточных результатов. Только пусть у тебя не сложится мнение, что если уж "машина не может, то и стараться нечего". Машина может ВСЕ, если ее правильно использовать..
3. В твоей программе нарушена логика. Посмотри вниметельно: фраза "Равенство не справедливо" в принципе не может быть напечатана, так как мы не можем выйти из цикла, пока не достигли точности Eps. Подумай, что нужно сделать, чтоб исправить это.
И приходи продолжать разговор.. ))
Теперь от меня, как от администратора.
М
Тут не принято дублировать темы. Начала тут: http://forum.pascal.net.ru/index.php?showtopic=19964&hl= - надо было тут и продолжать.. Учти это на будущее, пожалуйста