Показать сообщение отдельно
Старый 13.04.2014, 21:00   #7 (permalink)
Vladimir_S
Специалист
 
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
По умолчанию

Так, ну получите. Программа полностью отлажена.
А ошибка Ваша - в некорректной постановке условия выхода из цикла в подпрограмме поиска корня. Разность xl-xp вовсе не обязана уменьшаться. Нужно сравнивать предыдущее значение найденного корня с последующим, и когда разность между ними станет меньше меры точности, то прерывать цикл.
Код:
Const
 a=0;
 b=1.3;
 e=0.001;

Var
 c,Sq:Array[1..5] of real;
 i:integer;

function F(x,c:real):real;
begin
 F:=x*x*x+c*x-c;
end;

function Fint(x0,c:real):real;
var
 x,h,ss,sp,d:real;
 n,i:integer;
begin
 n:=100;
 sp:=0;
 Repeat
  ss:=0;
  h:=(b-x0)/n;
  x:=x0;
  for i:=1 to n do
   begin
    x:=x+h;
    ss:=ss+F(x,c)*h;
   end;
  d:=abs(sp-ss);
  sp:=ss;
  n:=2*n;
 Until d<=e;
 Fint:=ss;
end;

function COR(c:real):real;
var
 x_old,x_new,dif,xl,xp,U,V,D:real;
 p:boolean;
begin
 xl:=a;
 xp:=b;
 dif:=b-a;
 U:=F(xl,c);
 V:=F(xp,c);
 p:=false;
 while (dif>e) and not(p) do
  begin
   x_new:=xp-V*(xl-xp)/(U-V);
   D:=F(x_new,c);
   if U*D>0 then
    begin
     xl:=x_new;
     U:=D;
    end
   else
   if U*D<0 then
    begin
     xp:=x_new;
     V:=D;
    end
   else
   p:=true;
   dif:=abs(x_old-x_new);
   x_old:=x_new;
  end;
 COR:=x_new;
end;

Begin
 for i:=1 to 5 do
  begin
   c[i]:=i;
   Sq[i]:=Fint(Cor(c[i]),c[i]);
   writeln('c = ',c[i]:3:1,'   x0 = ',Cor(c[i]):0:5,'    Square = ',Sq[i]:0:5);
  end;
 Readln
End.
Vladimir_S вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070