skilk Опубликовано 8 мая, 2005 Жалоба Поделиться Опубликовано 8 мая, 2005 (изменено) Вычислить значение суммы членов бесконечного ряда S=-x+((x*x*x)/3)-...+((-1)*n)*(((x)*2n-1)/2n-1)+... с заданной точностью e=0.5*((10)*-4) На печать вывести значение суммы и число членов ряда, вошедших в сумму. ----------------- ОТ МОДЕРАТОРА: Называй темы в соответствии с правилами! Еще одно нарушение и ты повесишь на меня работу просматривать твои сообщения перед их публикацией. Изменено 8 мая, 2005 пользователем Сергей Плоткин Ссылка на комментарий Поделиться на другие сайты Поделиться
Grimm Опубликовано 8 мая, 2005 Жалоба Поделиться Опубликовано 8 мая, 2005 int N,j,i=0; long double ep=0.001,Summ=0,an=0; cout<<endl; i++; an=(((3*i)-2)*((3*i)+1)); if (an!=0) {an=(1/an); Summ=Summ+an;} while (an>=ep) { i++; an=(((3*i)-2)*((3*i)+1)); if (an!=0) {an=(1/an); Summ=Summ+an;} } cout<<"Dlya to4nosti 0,001 summa ryada ravna: "<<Summ<<endl; cout<<"Vsego : "<<i<<" 4lenov"<<endl; cout<<"Posledniy 4len raven: "<<an<<endl; функция не твоя и точность не твоя, однако если не совсем из детсада найдешь куда всунуть [mergetime]1115584776[/mergetime] да, кстаи ето на турбо сях, если что [mergetime]1115584931[/mergetime] и переменные N и i там не нужны, и может можно не long double а меньше дипазон Ссылка на комментарий Поделиться на другие сайты Поделиться
skilk Опубликовано 9 мая, 2005 Автор Жалоба Поделиться Опубликовано 9 мая, 2005 А на TurboPascale или на delphi как выглядеть будет... Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 9 мая, 2005 Жалоба Поделиться Опубликовано 9 мая, 2005 skilk: Мне кажется, у тебя ошибка в записи условия. В формуле первые члены ряда не соответствуют общему выражению для члена ряда. Возможно, ряд должен выглядеть так?: S=-x+x^3/3-...+(-1)^n*x^(2*n-1)/(2*n-1) Тут, как принято в программировании, ^ - знак возведения в степень, порядок выполнения операций - как в обычной математике (например, возведения в степень делаются сначала, умножения - потом). Тогда: PROGRAM Sequence; VAR n:Integer; x,p,s:Single; BEGIN Readln(x); n:=1; p:=-x; s:=p; WHILE Abs(p)>.5e-4 DO BEGIN n:=n+1; p:=-p*x*x*(2*n-3)/(2*n-1); s:=s+p; END; Writeln(s,n); END. Ссылка на комментарий Поделиться на другие сайты Поделиться
skilk Опубликовано 10 мая, 2005 Автор Жалоба Поделиться Опубликовано 10 мая, 2005 Тогда извеняюсь за описку(сомневался что степень так пишется). Тогда надо с точностью e=0.5*10^-4 Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 10 мая, 2005 Жалоба Поделиться Опубликовано 10 мая, 2005 skilk: Я так и сделал. Три замечания: а) в Pascal нет операции возведения в степень. Вместо этого есть специальная функция возведения в степень. Мне она тут не понадобилась, я получал каждый следующий член ряда из предыдущего простым умножением. Вообще-то в Pascal, так как в нем нет операции возведения в степень, знак ^ используется для другой цели. Но когда записывают формулу или задачу для себя, а не для компьютера, программисты часто используют не какой-то конкретный язык, а некоторую смесь языков, которая всем понятна. В этом смысле я и использовал обозначения в записи формулы для ряда в начале поста. Получилось в стиле Бейсика. б) 0.5*10^-4 - это запись не числа, а формулы: возвести 10 в степень -4 и умножить на это 0.5. Как я написал, такая запись формулы в стиле Бейсика, в Pascal вместо возведения степень надо было бы написать вызов функции возведения в степень, но в любом случае при такой записи будут проводиться все эти вычисления. А вот запись .5e-4 (или, что то же, 0.5e-4) - это запись не формулы, а именно числа, то же самое, что написать 0.00005, кстати, такая запись применяется во всех языках программирования, и программа тут считать ничего не будет, а сразу использует это число. Конечно, при счете по формуле получилось бы это же число, но тут компьютеру пришлось бы считать, а возведение в степень - нелегкая операция даже для компьютера (в его масштабах скорости, конечно). в) я исходил из того, что в условии имеется в виду абсолютная точность (чаще используют слово ошибка). Бывает еще относительная. Абсолютная - это если результат отличается от точного не больше чем на эти .5e-4. Бывает еще относительная ошибка - если результат отличается от точного не на число .5e-4, а на .5e-4 часть от точного результата. Какой именно вид у тебя задан, не написано, но обычно, если не указывают вид точности, имеется в виду абсолютная. P.S. Видишь, написать гораздо легче, чем описать :) Ссылка на комментарий Поделиться на другие сайты Поделиться
skilk Опубликовано 11 мая, 2005 Автор Жалоба Поделиться Опубликовано 11 мая, 2005 ;) Большое СПАСИБО!!! Ссылка на комментарий Поделиться на другие сайты Поделиться
skilk Опубликовано 11 мая, 2005 Автор Жалоба Поделиться Опубликовано 11 мая, 2005 ;) Чё то не получается? Дело втом, что я текст набрал, когда компилировать начинаю, то курсор на строку Readln(x); между ") и ;" выводит, и ругается. Говорит следующие Error 116: Must be in 8087 mode to compile this. Пишу в Turbo Pascale Ver. 7.1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 11 мая, 2005 Жалоба Поделиться Опубликовано 11 мая, 2005 skilk: Все ясно. Чтобы использовать тип Single, компилятор должен работать в режиме допустимости использования аппаратной поддержки вычислений с плавающей запятой, то есть в Options - Compiler - Numeric processing должно быть установлено значение 8087/80287. Но можно ничего в настройках Турбопаскаля не менять и использовать режим, в котором компилятор работает по умолчанию, тогда надо во второй строке программы Single заменить на Real. Так и советую сделать. Дальше, 0 в записи 0.5e-4 все-таки оказался необходимым, добавь его. Наследство того, что Паскаль создавал не американец. После этого все будет работать. Но чтобы удобнее было читать результаты, замени еще Writeln(s,n); на Writeln('s=',s,' n=',n); После запуска программы никакая подсказка на ввод значения x не выдается, программа просто ждет ввода значения x, мигая текстовым курсором. Значение надо вводить в виде 0.8 или 0.4 или, если хочешь, 5e-1, всегда завершая ввод нажатием клавиши Enter. Но помни, что вводимое значение должно быть меньше 1, иначе ряд не имеет конечной суммы и программа выдаст ошибку. При желании можешь внести в программу вывод подсказки для ввода, например, введи оператор Writeln('Введите x'); перед оператором Readln(x); Кроме того, сразу после вывода результата ты автоматически возвращаешься в экран с текстом программы. Это нормально, но чтобы не быть обескураженным, когда после ввода значения x сразу появится экран с текстом программы, надо знать, что чтобы увидеть экран ввода-вывода, надо нажать Alt+F5, а повторным нажатием возвращаешься снова в экран с текстом программы. Для отладки можно сделать немного удобнее, вставив после оператора вывода Writeln('s=',s,' n=',n); еще строку с оператором Readln; Тогда программа после вывода результата не сразу переключится на экран с текстом программы, а будет ждать нажатия клавиши Enter. Ссылка на комментарий Поделиться на другие сайты Поделиться
aleksvander Опубликовано 29 марта, 2006 Жалоба Поделиться Опубликовано 29 марта, 2006 Помогите решить пару задачек на Паскале ;) S=7x + 7x^3/3 + 7x^5/5 + ... + 7x^(2n+1)/(2n+1) и Вычислить бесконечную сумму с заданной точностью eps (eps>0). Считать, что точность достигнута, если очередное слагаемое по модулю меньше eps, - все последующие слагаемые можно уже не учитывать. S=x + (x^3)/3! + (x^5)/5! + ... + (x^(2n+1))/(2n+1)! + ...; Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 30 марта, 2006 Жалоба Поделиться Опубликовано 30 марта, 2006 (изменено) aleksvander: Так почти то же, с чего топик начинался. Только слегка подкорректировать соответственно изменившимся условиям. Первая задачка: var eps,S,T,X,X2,P:Real; begin Write('eps: '); ReadLn(eps); Write('x: '); ReadLn(X); T:=7*X; S:=T; X2:=X*X; P:=1; while Abs(T)>=eps do begin T:=T*X2*P; P:=P+2; T:=T/P; S:=S+T; end; WriteLn('S=',S); end. Вторая задачка: var eps,S,T,X,X2,P:Real; begin Write('eps: '); ReadLn(eps); Write('x: '); ReadLn(X); T:=X; S:=T; X2:=X*X; P:=1; while T>eps do begin T:=T*X2/(P+1)/(P+2); P:=P+2; S:=S+T; end; WriteLn('S=',S); end. Изменено 30 марта, 2006 пользователем Тролль Ссылка на комментарий Поделиться на другие сайты Поделиться
Romiras Опубликовано 30 марта, 2006 Жалоба Поделиться Опубликовано 30 марта, 2006 Советую почитать Вычисление пределов с помощью ряда Тейлора Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 30 марта, 2006 Жалоба Поделиться Опубликовано 30 марта, 2006 Romiras: Посмотрел это руководство. Прости: ужасно! :D Все достигается лобовой атакой, не считаясь с потерями. Готовую функцию возведения в степень автор программы использовать не хочет, а сам реализует ее кошмарно (на форуме разбиралось, как ее эффективно реализовать). Хотя на самом деле ее вообще использовать не надо. Кроме чистой математики, существует и вычислительная математика. Совершенно ни к чему каждый член ряда вычислять каждый раз полностью заново, надо пользоваться рекуррентными соотношениями (каждый следующий член ряда легко вычисляется через предыдущий). Ссылка на комментарий Поделиться на другие сайты Поделиться
Romiras Опубликовано 30 марта, 2006 Жалоба Поделиться Опубликовано 30 марта, 2006 Для начинающих самое то, по-моему. А что такое "готовая" функция возведения в степень? Я такой в Паскале не помню... :D А та реализация степени проста, как раз, как 5 копеек. Есть другие варианты? Насчёт рекуррентности согласен на 100%, но там просто принцип объясняется. Я статью дополню тогда. Вся фишка в том, что нужно только подставить формулу, и больше ничего не нужно. Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 30 марта, 2006 Жалоба Поделиться Опубликовано 30 марта, 2006 Romiras: А, это твоя статья? ИМХО, действительно лучше дополнить, уж очень неэффективно вычисление рядов "в лоб". Чтобы получить формулу для рекуррентного вычисления членов ряда, просто делим запись одного члена ряда на запись предыдущего члена ряда. Например, для синуса (x^i/i!) / ((x^(i-2)/(i-2)!) = x^2/(i*(i-1)) , так что новый член ряда каждый раз получается просто умножением старого на это выражение, без всяких факториалов и степеней (тут значения i меняется при переходе к следующему члену ряда каждый раз на 2). На самом деле это формальное доказательство, человеку проще использовать словесное описание: при переходе от(x^3/3!) к (x^5/5!) степень увеличивается на два, то есть надо множить на x^2, а знаменатель увеличивается в 5!/3! раз, то есть в 4*5. Аналогично будет и в будущем. Множить всегда придется на икс квадрат, а делить надо сначала на 4*5, потом на 6*7, потом на 8*9 и т.д., это легко запрограммировать. А вот функции возведения в степень в Turbo Pascal действительно нет, тут я перепутал Turbo Pascal с Turbo C, там такая функция называется Pow. Мне почему-то казалось, что Borland ее и в Turbo Pascal ввела. Но увы, чего нет, того нет. Каюсь и посыпаю себе голову пеплом . В Pascal для возведения в степень используется выражение exp(n*ln(x)), уже писал когда-то об этом. Без всяких циклов. Ссылка на комментарий Поделиться на другие сайты Поделиться
can4ec Опубликовано 15 апреля, 2006 Жалоба Поделиться Опубликовано 15 апреля, 2006 skilk: Мне кажется, у тебя ошибка в записи условия. В формуле первые члены ряда не соответствуют общему выражению для члена ряда. Возможно, ряд должен выглядеть так?: S=-x+x^3/3-...+(-1)^n*x^(2*n-1)/(2*n-1) Тут, как принято в программировании, ^ - знак возведения в степень, порядок выполнения операций - как в обычной математике (например, возведения в степень делаются сначала, умножения - потом). Тогда: PROGRAM Sequence; VAR n:Integer; x,p,s:Single; BEGIN Readln(x); n:=1; p:=-x; s:=p; WHILE Abs(p)>.5e-4 DO BEGIN n:=n+1; p:=-p*x*x*(2*n-3)/(2*n-1); s:=s+p; END; Writeln(s,n); END. А как этот пример будет на с++Builder написан тподскажи? Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 15 апреля, 2006 Жалоба Поделиться Опубликовано 15 апреля, 2006 (изменено) can4ec: Вот и попробовал бы написать сам, а если что-то не получилось бы, выложил сюда. Очень полезно переводить программы с одного языка на другой. Вычислительная часть, после объявления переменных int n; float x,p,s; может выглядеть почти как на Pascal: n=1; p=-x; s=p; while (abs(p)>.5e-4) {n=n+1; p=-p*x*x*(2*n-3)/(2*n-1); s=s+p;}; Или, "в стиле C", все вычисления можно записать одним оператором: for(n=2,s=p=-x; abs(p)>.5e-4; n++,s+=p) p*=-x*x*(2*n-3)/(2*n-1); P.S. И, конечно, не забыть ввод значения x и вывод значений s и n, их оформление - "по вкусу". Изменено 15 апреля, 2006 пользователем Тролль Ссылка на комментарий Поделиться на другие сайты Поделиться
can4ec Опубликовано 15 апреля, 2006 Жалоба Поделиться Опубликовано 15 апреля, 2006 can4ec: Вот и попробовал бы написать сам, а если что-то не получилось бы, выложил сюда. Очень полезно переводить программы с одного языка на другой. Вычислительная часть, после объявления переменных int n; float x,p,s; может выглядеть почти как на Pascal: n=1; p=-x; s=p; while (abs(p)>.5e-4) {n=n+1; p=-p*x*x*(2*n-3)/(2*n-1); s=s+p;}; Или, "в стиле C", все вычисления можно записать одним оператором: for(n=2,s=p=-x; abs(p)>.5e-4; n++,s+=p) p*=-x*x*(2*n-3)/(2*n-1); P.S. И, конечно, не забыть ввод значения x и вывод значений s и n, их оформление - "по вкусу". Ну вот я попробовал на Builder только че-то не пашет: { int x=2; float p; int n; float s; s=p=-x for(n=2;abs(p)>0.001;n++,s+=p) { p=(-1)^n*x^(2*n-1)/(2*n-1); } Edit1->Text=IntToStr(s);; } Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 15 апреля, 2006 Жалоба Поделиться Опубликовано 15 апреля, 2006 can4ec: Вообще-то на синтаксические ошибки должен указывать сам C++ Builder, у меня он не установлен, поэтому я за него: s=p=-x - нет точки с запятой в конце. p=(-1)^n*x^(2*n-1)/(2*n-1); } - в C++ нет операции возведения в степень, операция ^ в нем имеет другой смысл, а для возведения в степень используется функция pow. И тоже нет точки с запятой в конце оператора. Edit1->Text=IntToStr(s);; - IntToStr умеет преобразовывать целые, а что она преобразует тут? Хотя синтаксической ошибки тут нет. Самое опасное - когда программа работает, но делает не то, что от нее хотят. Ну и лишняя точка с запятой, хотя она тут ни на что не повлияет. Ссылка на комментарий Поделиться на другие сайты Поделиться
can4ec Опубликовано 16 апреля, 2006 Жалоба Поделиться Опубликовано 16 апреля, 2006 can4ec: Вообще-то на синтаксические ошибки должен указывать сам C++ Builder, у меня он не установлен, поэтому я за него: s=p=-x - нет точки с запятой в конце. p=(-1)^n*x^(2*n-1)/(2*n-1); } - в C++ нет операции возведения в степень, операция ^ в нем имеет другой смысл, а для возведения в степень используется функция pow. И тоже нет точки с запятой в конце оператора. Edit1->Text=IntToStr(s);; - IntToStr умеет преобразовывать целые, а что она преобразует тут? Хотя синтаксической ошибки тут нет. Самое опасное - когда программа работает, но делает не то, что от нее хотят. Ну и лишняя точка с запятой, хотя она тут ни на что не повлияет. Я не могу понять как это ты возводишь в степень. Придставим что x=1 тогда p=-1 , s=p=-1 n=2 p=1*1*1(2*2-1)/(2*2-1)=1/3; s=-1+1/3; Теперь n=3 p=1*1*1(2*3-1)/(2*3-1)=1/5 <---- новедь должно получится -1/5 Почему не отрицательное получается третье число? Ссылка на комментарий Поделиться на другие сайты Поделиться
can4ec Опубликовано 16 апреля, 2006 Жалоба Поделиться Опубликовано 16 апреля, 2006 int x=2; float p; int n; float s; for(n=2,s=-x;abs(s)>0.001;n++) { p=(pow(-1,n)*pow(x,2*n-1))/(2*n-1); s+=p; } Edit1->Text=FloatToStr(s); Я решил все сделать через pow спасибо. Хотел спросить мне кажется что модель надо брать не от abs(p) а вот так abs(s)? Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 16 апреля, 2006 Жалоба Поделиться Опубликовано 16 апреля, 2006 can4ec: Я не могу понять как это ты возводишь в степень. Я не возвожу в степень вообще. Члены ряда можно вычислять двумя способами: прямым и рекуррентным. Рекуррентный способ не требует возведения в степень. Прочитай то, что я написал Romires'у. Что такое рекуррентный способ? Например, берем ряд: 1, 2, 4, 8... Его можно вычислять так: 2º=1, 2¹=2, 2²=4, 2³=8... А можно иначе: 1, 2*1=2, 2*2=4, 2*4=8... Второй способ - рекуррентный, как видишь, мы обходимся без возведения в степень. Я вообще не понимаю, откуда ты взял свою формулу в сообщении, в котором ты просчитываешь пример вручную, это какой-то гибрид между формулами для двух способов. Кстати, сумму этого ряда можно посчитать еще проще - это всего лишь -arctg(x), но тогда программировать было бы просто нечего... Насчет abs(p) - это оценка величины остатка ряда по Лейбницу, который доказал, что точность вычисления суммы знакопеременного ряда равна первому отброшенному члену ряда. Использовать для оценки точности вычисления суммы abs(s) было бы неправильно - сама сумма ряда может быть и довольно большой, а вот точность определения этой суммы равна именно очередному члену ряда. А вообще зачем тебе начинать с вычислительной математики? Это же в первую очередь математика, и только потом программирование. Надо программировать то, что тебе понятно, и ты это объясняешь компьютеру. Например, программа для определения оптимального веса человека по его росту проще и интереснее. Или определение знака зодиака по дате рождения... Или расчет биоритмов... Да мало ли простых и полезных программ с понятной простому человеку тематикой можно придумать... Если тебе самому что-то не совсем понятно, компьютеру это будет непонятно вдвойне - он никогда не додумает за тебя, а, наоборот, воспользуется любой возможностью неправильно истолковать вроде бы понятные тебе вещи. Программирование очень похоже на объяснение, чего ты хочешь, марсианину. Все, что можно, будет понято не так. Ссылка на комментарий Поделиться на другие сайты Поделиться
Eliar Опубликовано 20 ноября, 2021 Жалоба Поделиться Опубликовано 20 ноября, 2021 вычислить сумму бесконечного ряда с погрешностью 0.001. s =x-x/2+x/3-+x/4 ...+(-1)x/n+.... при x=0.1, 0.3 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти