23.11.2012, 20:25 | #1 (permalink) |
Member
Регистрация: 23.11.2012
Сообщений: 14
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
|
Программа почти работает
вот код: Код:
#include <math.h> #include <stdio.h> #include <conio.h> long double fact(int N) { if(N < 0) // åñëè ïîëüçîâàòåëü ââåë îòðèöàòåëüíîå ÷èñëî return 0; // âîçâðàùàåì íîëü if (N == 0) // åñëè ïîëüçîâàòåëü ââåë íîëü, return 1; // âîçâðàùàåì ôàêòîðèàë îò íóëÿ - íå óäèâëÿåòåñü, íî ýòî 1 =) else // Âî âñåõ îñòàëüíûõ ñëó÷àÿõ return N * fact(N - 1); // äåëàåì ðåêóðñèþ. } int main() { double n, b, xn, xk, sh, t, x, sum, w, f; int i; //char string[105]; char Y,N; a1: while(1) { printf("Vvedite x nachal'noe, x konechnoe, sdvig, shag, tochnost'\n"); scanf("%lf%lf%lf%lf%lf", &xn,&xk,&b,&sh,&t); { printf("+---------------------------------------+\n"); printf("¦ X ¦cos(x+b) ¦ Function¦ N ¦\n"); printf("¦---------+---------+---------+---------¦\n"); for(x=xn;x<xk+sh/8;x+=sh) { sum=0.0; n=0.0; while(fabs(pow(x, n)*cos(b+3.14*n/2))/fact(n)>t) { n++; } for(i = 0.0; i<n; i++) sum+=pow(x, i)*cos(b+M_PI*i/2)/fact(i); printf("¦ %6.2f ¦ %6.3f ¦ %6.3f ¦ %6g ¦\n", x, cos(x+b), sum, n); } printf("+---------------------------------------+\n"); a2: printf("Prodolzhit' vichysleniya? (Y/N)\n"); } if(getche()=='Y') goto a1; if(getche()=='N') return 0; else goto a2; } return 0; } Не пойму почему после 35-ого элемента счет через ряд сбивается, и начинают вываливаться большие числа. |
23.11.2012, 20:25 | |
Helpmaster
Member
Регистрация: 08.03.2016
Сообщений: 0
|
Пожалуйста, не торопитесь решать все самостоятельно, просмотрите схожие проблемы Усилитель почти без деталей почти доработанный моддинг мой первый почти доделанный мод 2 мой первый и уже почти законченный мод |
23.11.2012, 20:55 | #2 (permalink) |
Специалист
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
|
Гм, на первый взгляд вроде всё правильно. К сожалению, сам на СИ не пишу, поэтому, если никто не поможет раньше, перепишу Вашу программу на Паскаль и погоняю. Но это будет не сию секунду. Может быть, завтра утром.
|
23.11.2012, 23:44 | #4 (permalink) |
Специалист
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
|
Ну вот, нарисовал. Не без внутренней борьбы, поскольку полностью разделяю мнение, что все эти переходы по меткам (GoTo) подлежат неукоснительному изгнанию, чего Вам на будущее советую. Дурной стиль и "лапша" в итоге. Ну ладно, это лирика. Вот что получилось:
Код:
Var b,xn,xk,x,sh,sum,t:real; n,i:Integer; YN:Char; Label a1,a2; Function fact(M:Integer):Extended; begin if M=0 then fact:=1 else fact:=M*fact(M-1); end; Begin a1: Writeln('Vvedite x nachal"noe, x konechnoe, sdvig, shag, tochnost'); Readln(xn,xk,b,sh,t); Writeln('+---------------------------------------+'); Writeln(' X cos(x+b) Function N '); Writeln('+--------+---------+---------+----------+'); x:=xn; Repeat sum:=0; n:=0; While abs(Exp(n*Ln(x))*cos(b+3.14*n/2))/fact(n)>t do n:=n+1; For i:=0 to n do sum:=sum+Exp(i*Ln(x))*cos(b+Pi*i/2)/fact(i); Writeln(x:6:2,Cos(x+b):11:3,sum:11:3,n:8); x:=x+sh; Until x>xk+sh/8; Writeln('+--------+---------+---------+----------+'); a2: Write('Prodolzit vychisleniya (Y/N)? '); Readln(YN); If YN='Y' then GoTo a1 else If YN='N' then Halt(0) else GoTo a2; End. вот с этого места - подробнее. Какие данные вводите? Что за "35-й элемент"? Не очень ясно. |
23.11.2012, 23:57 | #5 (permalink) |
Member
Регистрация: 23.11.2012
Сообщений: 14
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
|
Попробуйте использовать х от 1 до 100
|
Ads | |
Member
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
|
24.11.2012, 12:43 | #7 (permalink) |
Специалист
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
|
Понятно. У меня тоже получается "это":
Причем никакими ухищрениями "это" не одолевается. А пробовал я многое: переход на рекуррентный способ вычисления слагаемых (тогда можно исключить вычисление факториала в явном виде), исключения периодов косинуса, так, чтобы привести аргумент в диапазон -2π..2π - тщетно! Похоже, тут мы просто упёрлись в ограничения разрядных сеток или, скорее, адресации цифровых ЭВМ, то есть, хотя формально разложение функции Cos(x+b) работает для |x|<∞, реально начиная с нескольких десятков компьютер выдает всякую чушь. Подождем, может быть профессионалы подскажут что-нибудь в этом плане: я-то любитель-самоучка. А пока просто ограничьте диапазон аргументов, скажем, x+b<10. |
25.11.2012, 10:14 | #9 (permalink) |
Специалист
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
|
Вы неверно понимаете.
Суть проблемы в том, что следует представлять себе ответы на вопросы о применимости разложения функций в ряд Тейлора и об условиях достоверности аппроксимации значения функции конечной суммой членов такого ряда. Дело в том, что разложение в ряд Тейлора ведется всегда в окрестности некоей центральной точки, и чем ближе аргумент к этой точке, тем точнее приближение суммой конечного числа членов ряда, или тем меньше членов ряда нужно учесть, чтобы достичь требуемой точности. Если же мы уйдем далеко от центра, то тут возможны "сюрпризы". Рассмотрим наш случай. Здесь разложение ведется в окрестности х=0. И действительно, для небольших значений аргумента, в пределах одного-двух десятков, всё нормально. А вот дальше... Дальше, для больших аргументов, начинается серьёзная конкуренция между степенной функцией в числителе и факториалом в знаменателе, благодаря чему сначала модули слагаемых членов ряда в зависимости от номера начинают возрастать до огромных (порядка 10^20-10^30, ^ - возведение в степень) значений, а затем спадают, выходя практически на "плато". То же самое происходит и с суммой, только она "застывает" на значениях порядка 10^10-10^20, что мы и видим. Возникает вопрос - а почему же тогда в справочниках область применимости разложения указана, как |x|<∞? Всё правильно. Если Вы вообразите ЭВМ с бесконечноёмкой разрядной сеткой и просуммируете миллионы-миллиарды-триллионы-квинтильоны и т.д. членов ряда, то в конце концов придёте к нужному значению Вашего косинуса. Итог: повторяю - ограничьте диапазон значений аргумента. Это всё. Приложенные файлы иллюстрируют вышеприведенный анализ и содержат расчеты для малых и больших аргументов (значения - в первой строке файла). Колонка А (вторая) - это значения члена ряда под номером n. |
25.11.2012, 11:07 | #10 (permalink) |
Member
Регистрация: 23.11.2012
Сообщений: 14
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
|
А нельзя ли факториал задать без функции??
Скажем на основе вот этого примера: вариант 2 |
Ads | |
Member
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
|
|
|