Форум программистов, компьютерный форум, киберфорум
PascalABC.NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 16.12.2023
Сообщений: 2

Исправить программу нахождения суммы ряда

16.12.2023, 12:05. Показов 988. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вот условие:

https://www.cyberforum.ru/cgi-bin/latex.cgi?s=1+\cos\frac{\pi}{3}\cdot \frac{x}{1!}+\dots+\frac{\cos\:n\frac{\pi}{3}}{n!}x^n+\dots0.1210-4

Хочу найти ошибку в программе, программу прикреплю ниже
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
program lb3;
const eps=0.0001;
x=0.12;
var c,a,s:real;
n:integer;
d:longint;
begin
c:=1; a:=1; n:=0; s:=0; d:=1;
while abs(a)>=eps do
begin
n:=n+1;
c:=cos(n*pi/3);
d:=d*(2*n)*(2*n);|
a:=(c/d)*(x**n);
s:=s+a;
end;
writeln
('('Сумма ряда=',s:10:8);
writeln ('Количество членов ряда в сумме=',n);
end.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.12.2023, 12:05
Ответы с готовыми решениями:

Вычислить значение суммы бесконечного ряда с заданной точно-стью . Вывести значение суммы и число членов ряда
x=0,70. e=0,0001. Точное значение: chx. ...

Вычислить значение суммы бесконечного ряда с заданной точ- ностью E. Вывести значение суммы и число членов ряда, вошедши
Вычислить значение суммы бесконечного ряда с заданной точ- ностью E. Вывести значение суммы и...

Вычислить значение суммы бесконечного ряда с заданной точностью E. Вывести значение суммы и число членов ряда
1. Вычислить значение суммы бесконечного ряда с заданной точ- ностью . Вывести значение суммы и...

5
Модератор
10445 / 5737 / 3406
Регистрация: 17.08.2012
Сообщений: 17,454
17.12.2023, 01:18
Лучший ответ Сообщение было отмечено TEXHO_KOPCAP как решение

Решение

TEXHO_KOPCAP, Вы при регистрации на форуме обещали соблюдать правила форума. Пожалуйста, выполняйте Ваше обещание. Ссылка на правила есть на любой странице форума.
  • Темы называйте осмысленно.
  • Заключайте код в соответствующие теги, для этого есть кнопки в шапке редактора сообщения.
  • На будущее, вопрос описывайте максимально подробно. В данном случае понятно, что нужно найти сумму ряда с заданной точностью, однако, не всегда всё вот так очевидно. Возьмите за правило писать вопрос полностью.
На будущее:
  • На кой чорт фотография несуразной строки из таблицы, да ещё и с номером Вашего варианта? Лучше указывайте явно: x = 0.12, ε = 10-4, ряд имеет следующий вид: ... и далее приводите фотографию (только) формулы ряда, а лучше напишите формулу с помощью встроенного в форум редактора формул на основе LATEX (ниже окна для ввода сообщения, формулу копировать из нижнего поля после просмотра).
  • Форматируйте текст программы, причём не как попало, а в каком-либо общепринятом виде. Иначе текст программы плохо воспринимается, и ещё глаза режет. Невежливо как-то получается.
Задачка имеет особенность, поэтому заинтересовала меня. Преступим.

Разбор полётов.

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

Синтаксические ошибки спишем на Вашу невнимательность при копировании текста из одного места в другое.

Алгоритмические ошибки:
  • Нулевой член ряда не учтён. Перед циклом должно быть s := 1.
  • Факториал вычисляется неверно. Должно быть d := d * n.
  • Количество просуммированных членов ряда выводится неверно, Вы и здесь не учли нулевой член ряда. Количество слагаемых от 0 до n будет n+1, а не n (n членов от первого до n-го, плюс нулевой член)
  • Непосредственно вычислять факториал в программе, даже рекуррентно - это очень плохая идея, потому что n! растёт очень быстро, и в Вашем случае безошибочно можно вычислить только первые 14 членов, далее будет "тихое" (не вызывающее краха программы) переполнение переменной d, и поэтому программа в конечном счёте выдаст неверный результат (13! = 6227020800 > 231-1 = 2147483647). При Ваших входных данных Вам просто повезло.
  • На всякий пожарный: плохой идеей является и непосредственное вычисление xn при |x| > 1, особенно при достаточно больших x, почти по той же причине: рано или поздно xn будет больше максимального значения типа real, но будет уже не "тихое" переполнение, а вылет программы, поскольку xn примет специальное значение NaN (Not a Number - Не Число), арифметические операции с которым расцениваются как недопустимые, и попытка вычислить следующий член ряда приведёт к аварийному завершению программы. Но, в данном случае, норм, потому что x = 0.12. Типа, опять повезло.
  • Integer и longint в современных паскалях - Это одно и то же. Не одно и то же это только в Turbo / Borland Pascal и некоторых других древнейших паскалях.
  • Плохой формат вывода :10:8. Неизвестно, сколько будет знаков в целой части числа, поэтому лучше применить :0:8, например.
  • Первая строка со словом program уже лет 50 как необязательна.

При заданных x и ε Вашу программу можно уговорить выдать верный результат. Исправленная программа:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const 
  eps = 0.0001;
  x = 0.12;
var 
  c, a, s: real;
  n, d: integer;
begin
  c := 1; 
  a := 1; 
  n := 0; 
  s := 1; 
  d := 1;
  while abs(a) >= eps do
    begin
      n := n+1;
      c := cos(n * pi / 3);
      d := d * n;
      a := (c / d) * (x ** n);
      s := s + a
    end;
  writeln('Сумма ряда = ', s:0:8);
  writeln('Количество членов ряда в сумме = ', n + 1)
end.
Не торопитесь радоваться: это - не решение, это - детский лепет. Хотя... Можете сдать и это. Однако, я настоятельно рекомендую моё решение.

Приступим к решению.

Изменим развёрнутое описание ряда на нормальное, и обозначим xn/n! = a, cos(nπ/3) = b:

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
S=\sum_{n=0}^{\infty }\left(\frac{x^n}{n!}\cdot \cos\left(\frac{n\pi }{3} \right) \right)=\sum_{n=0}^{\infty}(a\cdot b)<br />

Разбиение члена ряда на два сомножителя нужно для упрощения нахождения критерия окончания вычислений: поскольку |cos(...)| ≤ 1, то можно определять окончание вычислений по bn=xn/n!.

Найдём рекуррентное соотношение для an.

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
\boxed{a_0=\frac{x^0}{0!}=1};\ \ a_n=\frac{x^n}{n!};\ \ a_{n-1}=\frac{x^{n-1}}{(n-1)!};\\\\\frac{a_n}{a_{n-1}}=\frac{\frac{x^n}{n!}}{\frac{x^{n-1}}{(n-1)!}}=\frac{x}{n}\ \Rightarrow \ \boxed{a_n=\frac{x\cdot a_{n-1}}{n}}<br />

Найдём рекуррентное соотношение для bn.

Можно, конечно, вычислять bn непосредственно, или воспользоваться формулой для косинуса суммы, но в данном случае, по-моему, проще составить таблицу:

n012345
Угол (радианы)0π/32π/3π4π/35π/3
Косинус угла10.5-0.5-1-0.50.5

Так как cos - функция периодическая, далее всё будет повторяться. Организуем в программе массив b с этими значениями с индексами от 0 до 5, и тогда будет bn = b[n mod 6].

Можно не использовать массив, а составить формулу для вычисления значений этой таблицы в зависимости от n mod 6, но это будет слишком громоздко.

Определимся с критерием окончания вычислений.

Cos(...) и x обеспечивают, что ряд обязательно будет не знакочередующийся, но и не знакопостоянный. Получается, что нельзя использовать признак Лейбница для нахождения критерия окончания вычислений. Будем использовать признак сравнения.

Так как |bn| ≤ 1, и bn ≠ 0, то и ряд из модулей членов Вашего ряда

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
S=\sum_{n=0}^{\infty }\left|\frac{x^n}{n!}\cdot \cos\left(\frac{n\pi }{3}\right) \right|<br />

будут меньше соответствующих членов ряда для экспоненты от модуля аргумента:

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
e^{|x|}=\sum_{n=0}^{\infty }\frac{|x^n|}{n!}<br />

известно, что остаток этого ряда не превосходит последнего члена ряда. Получаем критерий окончания вычислений:

https://www.cyberforum.ru/cgi-bin/latex.cgi?|a_n|<\varepsilon

Получился критерий окончания вычислений до безобразия похожий на критерий окончания вычислений по признаку Лейбница. Только вот... Самурай без меча подобен самураю с мечом, но без меча... Признак Лейбница сегодня чаще всего трактуют неверно. Типа, вычисления можно прекращать, если модуль очередного члена ряда становится меньше заданной точности.

Правильное определение признака Лейбница, в моей редакции. Нажмите + для прочтения.
Если модули членов знакопеременного ряда, начиная с члена с некоторым номером, монотонно убывают, то, начиная с упомянутого некоторого номера, остаток ряда не превосходит модуля последнего отброшенного члена ряда.


Возможны более строгие (но, увы, ненужные) варианты, и я их отсёк. Однако, я написал для Вас некоторые мои рассуждения под спойлером, если желаете, почитайте:

Нажмите + для прочтения.
Так как |bn| ≤ 1, и bn ≠ 0, то и ряд из модулей членов Вашего ряда

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
S=\sum_{n=0}^{\infty }\left|\frac{x^n}{n!}\cdot \cos\left(\frac{n\pi }{3}\right) \right|<br />

будут меньше соответствующих членов ряда

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
T=\sum_{n=0}^{\infty }\frac{|x^n|}{n!}<br />

k-й остаток этого ряда будет

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
T_k=\sum_{n=k}^{\infty }\frac{|x^n|}{n!}<br />

и, так как x < 1, этот остаток, в свою очередь, будет меньше суммы (убывающей) геометрической прогрессии c первым членом |xk/k!| = |ak| и знаменателем прогрессии x

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
P=\sum_{n=k}^{\infty }\frac{|x^n|}{k!}=\frac{x_k}{1-|x|}<br />

Тогда за критерий окончания вычислений можно принять

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
\frac{|x_k|}{1-|x|}<\varepsilon<br />

Всё хорошо, вот только есть проблема: если вдруг окажется, что x ≥ 1, то все эти рассуждения вроде как идут коту под хвост.

Однако, замечу, что всё-таки эти рассуждения верные, несмотря на вычисление суммы для неубывающей геометрической прогрессии с помощью суммы для убывающей геометрической прогрессии, но доказательство этого - это совершенно другая и очень длинная и нудная история.

Просто запишем все вот эти мои рассуждения в тренаж.

Можно также оценить остаток ряда с помощью интегрального признака Коши-Маклорена с использованием гамма-функции, но в этом случае всё получается слишком сложно, поскольку интеграл будет далеко не табличный.


Пишем программу.

Я вижу, что Вы, несмотря на то, что пишете в "классическом" стиле, используете Pascal ABC.NET. Не стоит этого делать, это примерно то же самое, что пилить дрова незаведённой бензопилой. Поэтому - извините, я буду писать на Pascal ABC.NET.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
##
  var (x, ε) := (0.12, 1E-4);
  var (s, a, n) := (1.0, 1.0, 0);
  var b: array[0..5] of real := (1.0, 0.5, -0.5, -1.0, -0.5, 0.5);
  while abs(a) > ε do
    begin
      n += 1;
      a *= x / n;
      s += a * b[n mod 6]
    end;
  $'Сумма ряда = {s}'.Println;
  $'Количество членов ряда в сумме = {n+1}'.Println
Даже в этой, казалось бы, со всех сторон правильной программе, есть подводный камень: если задать достаточно большой x и достаточно маленький ε, то будет неверный ответ. Дело в том, что при достаточно большом x с ростом n величина xn поначалу растёт быстрее, чем n!, и может возникнуть ситуация, когда вес младшего разряда мантиссы машинного представления суммы ряда s будет больше очередного члена ряда a * b[n mod 6], и поэтому все последующие слагаемые никак не повлияют на сумму ряда.

P. S.:

Если требуется "попсовое" решение, то замените
Pascal
9
      s += a * cos(n * pi / 3)
после чего удалите строку 4.

Если нужно пилить незаведённой бензопилой, то напишите, на каком именно диалекте паскаля Вам требуется программа, или напишите, что программа должна работать на всех диалектах паскаля, которые есть на нашем форуме. И я напишу для Вас то, что Вам требуется.

Есть подозрение, что учили Вас Turbo Pascal, а в качестве бесплатного компилятора порекомендовали Pascal ABC.NET.
1
0 / 0 / 0
Регистрация: 16.12.2023
Сообщений: 2
17.12.2023, 09:51  [ТС]
Добрый день, спасибо за объяснение задачи и извините, что писал тему не по правилам форума, впредь такого не повторится.
Хотел исправиться, нас учили на паскаль онлайн, я сам же делаю программы дома на Pascal ABC.NET, и некоторые функции я просто не знаю в ABC.NET поэтому мое решение задачи выглядит корявым
0
 Аватар для agvego5
48 / 39 / 10
Регистрация: 18.09.2023
Сообщений: 256
17.12.2023, 10:50
Цитата Сообщение от TEXHO_KOPCAP Посмотреть сообщение
нас учили на паскаль онлайн
это наверное FreePascal (FPC)
0
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
17.12.2023, 11:26
Цитата Сообщение от Cyborg Drone Посмотреть сообщение
var b: array[0..5] of real := (1.0, 0.5, -0.5, -1.0, -0.5, 0.5);
Pascal
1
var b := |1.0, 0.5, -0.5, -1.0, -0.5, 0.5|;
1
Модератор
10445 / 5737 / 3406
Регистрация: 17.08.2012
Сообщений: 17,454
17.12.2023, 12:07
TEXHO_KOPCAP,

Получается, что Вы не знаете, какому именно диалекту паскаля Вас учили. Скорее всего, Вас учили Turbo Pascal, он же TP.

В онлайн-компиляторах чаще всего используется Free Pascal Compiler, он же Free Pascal, он же FPC. При очередном сеансе работы посмотрите для интереса, что там компилятор пишет во время компиляции. Среди прочего, он назовёт самого себя, будет что-то типа Free Pascal Compiler ver. 3.2.

В FPC без переделки компилируется большинство программ для TP. Из оставшегося большинство программ компилируются, если в начало программы вставить строку с ключом компиляции {$MODE TP}. Не компилируются без переделки только те программы на TP, в алгоритме работы которых используется переполнение разрядной сетки 16-битных целых чисел, а также непосредственный доступ к битам машинного представления чисел в турбопаскалевском типе real, который на самом деле является ныне устаревшим типом real48.

Для любого диалекта паскаля:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const
  x = 0.12;
  eps = 1E-4;
  b: array[0..5] of real = (1, 0.5, -0.5, -1, -0.5, 0.5);
var
  s, a: real;
  n: integer;
begin
  a := 1;
  s := a;
  n := 0;
  while abs(a) > eps do
    begin
      inc(n);
      a := a * x / n;
      s := s + a * b[n mod 6]
    end;
  writeln('Сумма ряда = ', s:0:8);
  writeln('Количество членов ряда в сумме = ', n + 1);
  readln
end.
Если не нравится вычисление cos с помощью константного массива, то замените
Pascal
16
      s := s + a * cos(n * pi / 3)
и удалите строку 4.

Теоретически, от такой коррекции может пострадать точность вычислений из-за неявного преобразования сопроцессором достаточно большого аргумента для cos в диапазон [0; π/4]. Например, если написать
Pascal
1
2
3
4
begin
  writeln(cos(100000*pi/3):0:16);
  readln
end.
то будет напечатано -0.5000000000098036, а не -0.5000000000000000, как планировалось.

Если Вы сдаёте программу роботу на проверочный сайт, и робот чего-то там ругается, то замените конец программы на
Pascal
18
19
  writeln(s, ' ', n + 1);
end.
Если робот продолжает ругаться, выясните, в каком именно формате он желает увидеть результат, и подправьте вывод. Например, если он желает сумму с 4 знаками после десятичной точки, то подрихтуйте вот так:
Pascal
18
19
  writeln(s:0:4, ' ', n + 1);
end.
Добавлено через 17 минут
Sun Serega, вечно я об || забываю.

Добавлено через 13 минут
Вот ведь... Опечатался, написал b[n mod 10]...

Исправил.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.12.2023, 12:07
Помогаю со студенческими работами здесь

Вычислить значение суммы бесконечного ряда с заданной точностью. Вывести значение суммы и число членов ряда
Вычислить значение суммы бесконечного ряда с заданной точностью. Вывести значение суммы и число...

Составить алгоритм и программу нахождения суммы ряда с заданной точностью Е
У меня проблемы с паскалем((( Уже не знаю что делать, куда бежать! Помогите пожалуйста програмку...

Составить алгоритм и программу нахождения суммы значений натурального ряда чисел, которые кратны 5 и не больше 200
Составить алгоритм и программу нахождения суммы значений натурального ряда чисел, которые кратны 5...

Составить и отладить программу для нахождения суммы ряда
Построить алгоритм, составить и отладить программу для нахождения суммы ряда: ...

Составить алгоритм и программу нахождения суммы ряда с заданной точностью Е
Составить алгоритм и программу нахождения суммы ряда с заданной точностью Е. Использовать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
1С: Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru