Помощь - Поиск - Пользователи - Календарь
Полная версия: Помогите решить проблему (ошибка 205 в программе) при описание метода решение СЛАУ
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Error 205
Доброго времени суток!
При решение программы выходит ошибка 205 (ф-ия с плавающей точкой вывела слишком большое значение для паскаля). Как от нее избавиться?

Вот листинг программы:

uses crt;
const eps=0.001;

var
a:array [1..50, 1..50] of integer;
ab,t,b,c,d:array [1..50] of real;
x,xx,r:array [0..50, 0..50] of real;
n,i,j,k: integer; rr,rr1:real;
p:boolean; ii:longint;

procedure init;
begin
clrscr;
writeln('Ax=B');
writeln('BBeguTe IIop9goK cucTeMbI');
readln(n);
writeln('BBeguTe A'); {vvodim A}
for i:=1 to n do
begin
for j:=1 to n do
begin
writeln('BBeguTe a[',i,',',j,'] eJIeMeHt MaccuBa');
read(a[i,j]);
end;
readln;
end;
clrscr;
writeln('Ax=B');
writeln('BBeguTe B');
for i:=1 to n do {vvodim b}
begin
writeln('BBeguTe b[',i,'] eJIeMeHt MaccuBa');
read(b[i]);
end;
clrscr;
writeln('Ax=B');
for i:=1 to n do
begin {vvodim x^0}
writeln('BBeguTe Ha4aJIbHoe IIpubJIu}I{eHue');
read(x[i,0]);
end;
readln;
end;

procedure raschet1; {schitaem r^0 - vektor nevyazki}
begin
for i:=1 to n do
begin
c[i]:=0;
j:=0;
repeat
inc(j);
c[i]:=c[i]+(a[i,j]*x[j,ii-1]); {***}
until j=n;
r[i,ii-1]:=b[i]-c[i];
end;
end;


procedure raschet2; {schitaem tay 4epe3 ckaJI9pHoe proizvedenie}
begin
rr:=0; rr1:=0; t[ii]:=0;
for i:=1 to n do
begin
rr:=rr+r[i,ii-1]*r[i,ii-1]; {***}
d[i]:=0;
for j:=1 to n do
begin
d[i]:=d[i]+(a[i,j]*r[j,ii-1]);
end;
rr1:=rr1+d[i]*r[i,ii-1]; {***}
end;
t[ii]:=rr/rr1;
end;

procedure raschet3; {schitaem x^i-Toe}
begin
for i:=1 to n do
begin
xx[i,ii]:=t[ii]*r[i,ii-1];
x[i,ii]:=xx[i,ii]+x[i,ii-1];
end;
end;


procedure vyv; {print}
begin
clrscr;
writeln('MaTpuLLa A=');
for i:=1 to n do
begin
for j:=1 to n do
begin
write(a[i,j]:2);
end;
writeln;
end;
readln;
{clrscr;}
writeln('MaTpuLLa B=');
for i:=1 to n do
begin
writeln(B[i]:3 :0);
end;
readln;
{clrscr;}
writeln('Ha4aJIbHoe IIpubJIu}I{eHue x^0=');
for i:=1 to n do
begin
writeln(x[i,0]:3 :0);
end;
readln;
{ clrscr;}

end;


procedure proverka; {proverka na pogpewHocTb}
begin
ab[ii]:=0;
p:=false;
for i:=1 to n do
ab[ii]:=ab[ii]+sqr(x[i,ii]-x[i,ii-1]);
if abs(sqrt(ab[ii]))<eps then
begin
p:=true;
clrscr;
writeln('OKOH4aTeJIbHbIu OTBET= ');
for i:=1 to n do
begin
writeln(x[i,ii]:7 :3);
end;
readln;
halt
end;
end;


begin
init;
vyv;
repeat
for ii:=1 to 50000 do begin

raschet1;
raschet2;
raschet3;
proverka;
end;
until p=true;
end.


Программа должна решать СЛАУ методом скорейшего спуска. Ошибка выходит в строках помеченных {***}. При решение матриц 2х2 иногда просчеты идут, но при большей размерности выскакивает ошибка 205 почти всегда в помеченных строках... Очень прошу объясните что не так и по возможности исправьте..... Заранее благодарю, с уважением, Вадим smile.gif .
volvo
Исходные данные, на которых у тебя сбой - в студию. В общем случае могу посоветовать только {$N+} для включения сопроцессора, и изменение типа real на extended, имеющий ГОРАЗДО большую емкость, хотя 50 тысяч циклов любой тип может не выдержать.
Error 205
Исходные данные:
Матрица А:
1 2 3
1 2 3
1 2 3
Матрица В:
1
2
3
Начальное приближение:
1
2
3
________________
Ну это к примеру.
50000 циклов для более точного вычисления идет, так как погрешность exp маленькая. Если же я вместо real обозначу extended то у меня появляются ошибка в строчках
 procedure raschet2;	  {schitaem tay 4epe3 ckaJI9pHoe proizvedenie}
begin
rr:=0; rr1:=0; t[ii]:=0; <<<<<<<<<<< Здесь
for i:=1 to n do
begin


Можете объяснить что такое сопроцессор {$N+} и как его подключать?
P.S.: как раз при замене real на extended появляется ошибка связанная с {$N+}
volvo
Цитата
Можете объяснить что такое сопроцессор {$N+} и как его подключать?
Сопроцессор. Чтобы подключать - достаточно написать эту самую директиву {$N+} самой первой строкой программы.

Цитата
как раз при замене real на extended появляется ошибка связанная с {$N+}
Ошибка (в строке
Цитата
rr:=0; rr1:=0; t[ii]:=0;
) у тебя появляется из-за вылета за пределы массива: массив t описан как array [1..50] of real, а значение ii перед вылетом = 51, сделай тестовую печать:
	 procedure raschet2;	  {schitaem tay 4epe3 ckaJI9pHoe proizvedenie}
begin
rr:=0; rr1:=0;
writeln(ii);
t[ii]:=0;
...

и убедись в этом... Вот тебе и результат использования глобальных переменных, где-то она меняется, а чтобы понять, где - надо копаться во всей программе. А ведь предупреждали: глобальные переменные - зло.
Error 205
Спасибо за совет про сопроцессор. Тепрь при средней погрешности считает в 50% случаев.
Цитата
Вот тебе и результат использования глобальных переменных, где-то она меняется, а чтобы понять, где - надо копаться во всей программе. А ведь предупреждали: глобальные переменные - зло.


то есть мне надо сделать переменную ii локальной? Но она же счетчик выполнения процедур... Как быть в этом случае?
Error 205
{$N+}
uses crt;
const eps=0.1; n=3;
Type
mas2 = array [1..n, 1..n] of real;
mas1 = array [1..n] of extended;
var
a:mas2;
c,b,d,r,x,x1,p:mas1;
t,rr,rr1:extended;

procedure init(var a:mas2; var b:mas1 );
var i,j:integer;
begin
clrscr;
writeln('Ax=B');
writeln('BBeguTe A');
for i:=1 to n do
begin
for j:=1 to n do
begin
write('BBeguTe a[',i,',',j,'] eJIeMeHt MaccuBa ');
readln(a[i,j]);
end;
writeln;
end;

writeln('Ax=B');
writeln('BBeguTe B');
for i:=1 to n do
begin
write('BBeguTe b[',i,'] eJIeMeHt MaccuBa ');
readln(b[i]);
end;
clrscr;
writeln('Ax=B');
end;

procedure summ(a,b:mas1; var x:mas1);
var i:integer;
begin
for i:=1 to n do x[i]:=a[i]+b[i];
end;

procedure umnog(a:mas2; b:mas1; var c:mas1);
var i, j :integer;
begin
for i:=1 to n do
begin
c[i]:=0;
for j:=1 to n do c[i]:=c[i]+(a[i,j]*b[j]);
end;
end;

procedure umnog2(var r:mas1; t:real);
var i:integer;
begin
for i:=1 to n do
r[i]:=r[i]*t;
end;

procedure raznost(b,c:mas1; var r:mas1);
var i:integer;
begin
for i:=1 to n do
r[i]:=b[i]-c[i];
end;

function scalar(a,b:mas1 ):extended;
var i : integer;
x : extended;
begin
x:=0;
for i:=1 to n do
x:=x+a[i]*b[i];
scalar := x;
end;

function norma(x:mas1): real;
var
i : integer;
ab : real;
begin
ab:=0;
for i:=1 to n do ab:=ab+sqr(x[i]);
norma := sqrt(ab);
end;

procedure vyv(a:mas2) ;
var i,j:integer;
begin
for i:=1 to n do
begin
for j:=1 to n do write(a[i,j]:6:2);
writeln;
end;
end;

procedure view(x:mas1);
var
i : integer;
begin
for i:=1 to n do writeln(x[i]:6:2);
end;



begin
init(a,b);
x := b;
writeln('matrix A');
vyv(a);
writeln('matrix B');
view(B);
repeat
x1:=x;
umnog(a,x,c);
raznost(b,c,r);
rr := scalar(r,r);
umnog(a,r,d);
rr1 := scalar(d,r);
t:=rr/rr1;
umnog2(r,t);
summ(r,x,x);
raznost (x1,x,p) ;
writeln('matrix x');
view(x);
readkey;
until norma(p)<eps;
writeln('matrix X');
view(X);
readkey;
end.


я исправил кое что.... сейчас стало более понятно.... но ошибка 205 всё равно возникает... что делать?
volvo
Я правильно понимаю, что алгоритм взят такой (заглавные буквы - матрицы):
повторять
X1 = X
R = B - A*X
rr = R*R
rr1 = (A*R)*R
t = rr / rr1
X = R*t + X
P = X1 - X
пока норма(P) не станет меньше eps
? Откуда ты взял его, можно полюбопытствовать?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.