Столкнулся с одной проблемой, 2 дня уже бьюсь... что делать - не знаю... Если коротко, то дело вот в чем. Я написал процедуру для подсчета определителя матрицы любого порядка (методом Гаусса). И там над матрицей выполняются различные преобразования (складывания строк и т.д.). Причем - внимание - по условию задания матрица должна быть обязательно динамической! Процедура работает нормально, определитель находит, НО в то же время изменяет исходную матрицу, а этого нельзя допустить!! Происходит это, как мне кажется, из-за того, что такие матрицы - ссылки на память, поэтому передать ее в процедуру строго по значению нельзя...
Замучился я с этими динамическими структурами... Please, умные люди, help me!
ОК, ошибка "Floating divizion by zero" устранена... Мне надо ставить 2 за внимательность...
Но осталась 2-я ошибка - "Invalid floating point operation". Итак, код такой:
function Opred_Gauss(A:TDMAtr):real; // Описание переменных... var i,j,jk,ik,new:integer; tmp,mnoj,mn1,mn2:real; found:boolean; AC:TDMAtr; const eps = 1e-10; begin { Это то самое копирование матрицы } setlength(ac, length(a)); for i := 0 to pred(length(a)) do begin setlength(ac[i], length(a[i])); for j := 0 to pred(length(a[i])) do ac[i, j] := a[i, j] end; { А теперь - сам алгоритм } for i := 0 to high(AC) do begin if abs(ac[i,i])<eps then begin result :=0.0; exit end; for j := succ(i) to high(AC) do begin mnoj:=a[j,i]/a[i,i]; for jk:=i to high(AC) do a[j,jk]:=a[j,jk]-mnoj*a[i,jk]; end; end; result := 1.0; for i:=1 to high(AC) do result:=result*a[i,i]; end;
При данных
1 1 1 1 1 1 1 1 1
возникает вышеописанная ошибка в той же строке mnoj:=a[j,i]/a[i,i];
Немного помучившись и покапавшись в справочниках, нашел, что это бывает связано с проблемами сопроцессора, и устраняется путем добавления строчки
asm FINIT end;
тогда вместо ошибки возвращается константа NAN.
Окончательный вариант кода выглядит так:
function Opred_Gauss(A:TDMAtr):real; // Описание переменных... var i,j,jk,ik,new:integer; tmp,mnoj,mn1,mn2:real; found:boolean; AC:TDMAtr; const eps = 1e-10; begin asm FINIT end;
{ Это то самое копирование матрицы } setlength(ac, length(a)); for i := 0 to pred(length(a)) do begin setlength(ac[i], length(a[i])); for j := 0 to pred(length(a[i])) do ac[i, j] := a[i, j] end; { А теперь - сам алгоритм } for i := 0 to high(AC) do begin if abs(ac[i,i])<eps then begin result :=0.0; exit end; for j := succ(i) to high(AC) do begin mnoj:=a[j,i]/a[i,i]; for jk:=i to high(AC) do a[j,jk]:=a[j,jk]-mnoj*a[i,jk]; end; end; result := 1.0; for i:=1 to high(AC) do result:=result*a[i,i]; If Result = NAN then Result:=0; end;
Вот теперь (!) все работает без ошибок... УРА!
Но интересно, есть ли другие пути решения проблемы, без асмы? И отчего она все-таки, эта ошибка?