Форум программистов, компьютерный форум, киберфорум
Наши страницы

Delphi для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
Andbiz
0 / 0 / 0
Регистрация: 03.10.2011
Сообщений: 6
#1

Ошибка "Invalid floating point operation" при расчете обратной матрицы - Delphi

03.10.2011, 15:38. Просмотров 1330. Ответов 11
Метки нет (Все метки)

По учебе столкнулся с расчетом обратной матрицы. Смутил минор матрицы. Математически понимаю, как он находится, но программно не совсем понял. Пересмотрел множество примеров в Интернете, но понял, что лучше попытаться написать свою программу. Но при запуске программы происходит ошибка "Invalid floating point operation" на строке "C[i,j]:=((i+j)*ln(-1)*det_1)/det; // рассчитываю соответствующий элемент матрицы С" программы. Что я сделал неправильно?

Код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
begin
 det:=1.0;
 // начинаю прямой ход Гаусса
 for k:=1 to n do
 begin
 det:=det*A[k,k];//вычисление определителя
 for j:=k+1 to n do
 begin
 A[k,j]:=A[k,j]/A[k,k];
 end;
 for i:=k+1 to n do//начало вложенного цикла
 for j:=k+1 to m do
 begin
 r:=A[k,j]*A[i,k];
 A[i,j]:=A[i,j]-r;
 end;
 end;
 Edit1.Text:=FloatToStr(det);
 // Делаю транспонирование матрицы А
 begin
 for i:=1 to n do // начинаю цикл обхода всех строк и столбиков матрицы А
 for j:=1 to m do
 begin
 for i_1:=1 to n do // начинаю второй цикл обхода матрицы А, в котором будут отсеиваться одна строка и один столбик
 for j_1:=1 to m do
 if (i_1<>i) and (j_1<>j)
 then
 for l:=1 to n-1 do // заполняю матрицу D, считая, что количество строк алгебраического дополнения на одну меньше, чем матрицы А
 for p:=1 to m-1 do // заполняю матрицу D, считая, что количество столбцов алгебраического дополнения на одного меньше, чем матрицы А
 A[i,j]:=D[l,p]; // вношу соответствующий элемент в временную матрицу D
 end;
 begin
 det_1:=1.0;
 // начинаю прямой ход Гаусса
 for k:=1 to n-1 do
 begin
 det_1:=det_1*D[k,k]; //вычисление определителя
 for j:=k+1 to n-1 do
 begin
 D[k,j]:=D[k,j]/D[k,k];
 end;
 for i:=k+1 to n-1 do //начало вложенного цикла
 for j:=k+1 to m-1 do
 begin
 r:=D[k,j]*D[i,k];
 D[i,j]:=D[i,j]-r;
 end;
 end;
C[i,j]:=((i+j)*ln(-1)*det_1)/det; // рассчитываю соответствующий элемент матрицы С
 StringGrid_C.Cells[j-1,i-1]:=FloatToStr(C[i,j]) // вношу рассчитанный элемент в матрицу
 end;
 end;
 end;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.10.2011, 15:38
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Ошибка "Invalid floating point operation" при расчете обратной матрицы (Delphi):

Ошибка "Invalid floating point operation" при табулировании функции - Delphi
Здравствуйте!Выполняю ргр по информатике по теме табулирование функции, написана программа можно сказать не оч профессиональными руками,...

Ошибка "Invalid floating point operation" при вычислении значения функции - Delphi
Вычислить с точностью е корень уравнения x^4 + 0.8x^3 - 0.4x^2 -1.4x -1.2 = 0 . Использовать метод деления отрезка пополам. Искать...

О чем говорит ошибка "Invalid floating point operation" - Delphi

Ошибка "invalid floating point operation" - Delphi
вроде бы вылетает на строке F:=round(2*exp(x1*(k-1))-(3.5*(sin(x1*k)))); вообще формула должна быть такая f(x)=2*e^(1-x)-3,5*sin(x) это...

Ошибка "Invalid floating point operation" - Delphi
Люди добрые помогите, при рисовании графика выдает такую ошибку. Весь интернет обшарил, но не понял где у меня ошибка. Вот код: unit...

"Invalid floating point operation" при запуске - Delphi
программа после запуска выдает ошибку не могу понять где напутал помогите отладить unit Unit1; interface uses Windows,...

11
Ksana_
92 / 46 / 8
Регистрация: 11.02.2010
Сообщений: 187
03.10.2011, 15:43 #2
Массив C[i][j] у вас объявлен, как содержащий вещественный тип??
0
Andbiz
0 / 0 / 0
Регистрация: 03.10.2011
Сообщений: 6
03.10.2011, 15:51  [ТС] #3
Да, я объявил матрицу С вещественной (real).

Привожу текст всей программмы. В ней в середине другие действия с матрицей (умножения, деления, сложения и т.п.) - они работают нормально. Расчет обратной матрицы в конце.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
procedure TForm1.Button_CalcClick(Sender: TObject);
          const n_max=15;  // максимальное число строк матриц равно 15
          const m_max=15;  // максимальное число столбцов матриц равно 15
          type matr_1=array [1..n_max, 1..m_max] of real;  // числа строк и столбцов матриц - любые числа
          type matr_2=array [1..n_max, 1..m_max] of real;  // числа строк и столбцов матриц - любые числа
          var n,m:integer;  // число строк и столбцов - целое число
          var a,b:matr_1;  // a, b - это матрицы, элеметы которых любые числа
          var c,d:matr_2;  // c - это матрица с возможными дробями в качестве элементов матрицы
          i,j,i_1,j_1,l,p,k:integer;  // индексы i и j - целые числа
          r,det,det_1,s:real;  // det - определитель системы, r - произведение при прямом ходе
begin
     // Ввод размерности матриц и настройка компонентов StringGrid (матриц)
     n:=StrToInt(Edit_n.Text);  // Принимаю число строк равным n
     m:=StrToInt(Edit_m.Text);  // Принимаю число строк равным m
     StringGrid_A.RowCount:=n;  // для матрицы А число строк принимаю равным n
     StringGrid_A.ColCount:=m;  // для матрицы А число столбцов принимаю равным m
     StringGrid_B.RowCount:=n;  // для матрицы B число строк принимаю равным n
     StringGrid_B.ColCount:=m;  // для матрицы B число столбцов принимаю равным m
     StringGrid_C.RowCount:=n;  // для матрицы C число строк принимаю равным n
     StringGrid_C.ColCount:=m;  // для матрицы C число столбцов принимаю равным m
 
     // Ввод матрицы А
     if (RadioGroup1.ItemIndex=0)  // заполнение вручную
     then for i:=1 to n do
              for j:=1 to m do
                  A[i,j]:=StrToInt(StringGrid_A.Cells[j-1,i-1])
     else  for i:=1 to n do  // заполнение случайными числами
           for j:=1 to m do
           begin
                A[i,j]:=Random(101);  // случайное число от 0 до 100
                StringGrid_A.Cells[j-1,i-1]:=FloatToStr(A[i,j]) // вношу полученное значение в матрицу А
           end;
 
     // Ввод матрицы B
     if (RadioGroup2.ItemIndex=0)  // заполнение вручную
     then for i:=1 to n do
              for j:=1 to m do
                  B[i,j]:=StrToInt(StringGrid_B.Cells[j-1,i-1])
     else  for i:=1 to n do  // заполнение случайными числами
           for j:=1 to m do
           begin
                B[i,j]:=Random(101);  // случайное число от 0 до 100
                StringGrid_B.Cells[j-1,i-1]:=FloatToStr(B[i,j]) // вношу полученное значение в матрицу B
           end;
 
     // Заполнение матрицы С
     if (RadioGroup3.ItemIndex=0)  // сложить матрицы (А+В)
     then for i:=1 to n do
          for j:=1 to m do
          begin
               C[i,j]:=A[i,j]+B[i,j];  // процедура сложения элементов матриц
               StringGrid_C.Cells[j-1,i-1]:=FloatToStr(C[i,j]) // вношу полученное значение в матрицу С
          end
     else
         if (RadioGroup3.ItemIndex=1)  // вычесть матрицы (А-В)
         then for i:=1 to n do
              for j:=1 to m do
              begin
                   C[i,j]:=A[i,j]-B[i,j];  // процедура вычитания элементов матриц
                   StringGrid_C.Cells[j-1,i-1]:=FloatToStr(C[i,j]) // вношу полученное значение в матрицу С
              end
         else
             if (RadioGroup3.ItemIndex=2)  // перемножить матрицы (А*В)
             then for i:=1 to n do
                  for j:=1 to m do
                  begin  // начинаю цикл расчета элемента С [i,j]
                       s:=0;
                       for k:=1 to n do
                       s:=s+A[i,k]*B[k,j];
                       C[i,j]:=s;
                  StringGrid_C.Cells[j-1,i-1]:=FloatToStr(C[i,j]) // вношу полученное значение в матрицу С
                  end
             else
                 if (RadioGroup3.ItemIndex=3)  // транспонировать матрицу А
                 then for i:=1 to n do
                      for j:=1 to m do
                      begin
                           StringGrid_C.Cells[j-1,i-1]:=StringGrid_A.Cells[i-1,j-1];  // замена элемента строки на противоположный элемент столбцами
                      end
                 else
                     if (RadioGroup3.ItemIndex=4)  // транспонировать матрицу B
                     then for i:=1 to n do
                          for j:=1 to m do
                          begin
                               StringGrid_C.Cells[j-1,i-1]:=StringGrid_B.Cells[i-1,j-1];  // замена элемента строки на противоположный элемент столбцами
                          end
                     else
                         if (RadioGroup3.ItemIndex=5)  // вычисляю обратную матрицу А
                         then
                         begin
                         det:=1.0;
                         // начинаю прямой ход Гаусса
                         for k:=1 to n do
                         begin
                              det:=det*A[k,k];//вычисление определителя
                              for j:=k+1 to n do
                              begin
                                   A[k,j]:=A[k,j]/A[k,k];
                              end;
                              for i:=k+1 to n do//начало вложенного цикла
                              for j:=k+1 to m do
                              begin
                              r:=A[k,j]*A[i,k];
                              A[i,j]:=A[i,j]-r;
                              end;
                         end;
                         Edit1.Text:=FloatToStr(det);
                         // Делаю транспонирование матрицы А
                         begin
                              for i:=1 to n do  // начинаю цикл обхода всех строк и столбиков матрицы А
                              for j:=1 to m do
                              begin
                                   for i_1:=1 to n do // начинаю второй цикл обхода матрицы А, в котором будут отсеиваться одна строка и один столбик
                                   for j_1:=1 to m do
                                       if (i_1<>i) and (j_1<>j)
                                       then
                                           for l:=1 to n-1 do // заполняю матрицу D, считая, что количество строк алгебраического дополнения на одну меньше, чем матрицы А
                                           for p:=1 to m-1 do // заполняю матрицу D, считая, что количество столбцов алгебраического дополнения на одного меньше, чем матрицы А
                                           A[i,j]:=D[l,p]; // вношу соответствующий элемент в временную матрицу D
                              end;
                              begin
                                   det_1:=1.0;
                                   // начинаю прямой ход Гаусса
                                   for k:=1 to n-1 do
                                   begin
                                        det_1:=det_1*D[k,k];  //вычисление определителя
                                        for j:=k+1 to n-1 do
                                        begin
                                             D[k,j]:=D[k,j]/D[k,k];
                                        end;
                                        for i:=k+1 to n-1 do  //начало вложенного цикла
                                        for j:=k+1 to m-1 do
                                        begin
                                             r:=D[k,j]*D[i,k];
                                             D[i,j]:=D[i,j]-r;
                                        end;
                                   end;
                                   C[i,j]:=((i+j)*ln(-1)*det_1)/det; // рассчитываю соответствующий элемент матрицы С
                                   StringGrid_C.Cells[j-1,i-1]:=FloatToStr(C[i,j])  // вношу рассчитанный элемент в матрицу
                              end;
                          end;
                          end;
end;
 Комментарий модератора 
Для оформления кода Delphi, используйте специальный тег DELPHI на тулбаре редактора сообщений!
0
Ksana_
92 / 46 / 8
Регистрация: 11.02.2010
Сообщений: 187
03.10.2011, 15:58 #4
Цитата Сообщение от Andbiz Посмотреть сообщение
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
begin 
 det_1:=1.0;
 // начинаю прямой ход Гаусса 
 for k:=1 to n-1 do 
   begin 
     det_1:=det_1*D[k,k]; //вычисление определителя 
     for j:=k+1 to n-1 do 
         begin 
            D[k,j]:=D[k,j]/D[k,k]; 
         end; 
     for i:=k+1 to n-1 do //начало вложенного цикла 
     for j:=k+1 to m-1 do 
         begin r:=D[k,j]*D[i,k]; D[i,j]:=D[i,j]-r; 
         end; 
    end; 
C[i,j]:=((i+j)*ln(-1)*det_1)/det; // рассчитываю соответствующий элемент матрицы С 
StringGrid_C.Cells[j-1,i-1]:=FloatToStr(C[i,j]) // вношу рассчитанный элемент в матрицу end;
C[i][j] у вас находится вне тела цикла, может в этом проблема
0
Dzhej-Dzhej
Заблокирован
03.10.2011, 15:59 #5
ln(-1) - вот это непонятно.
0
Andbiz
0 / 0 / 0
Регистрация: 03.10.2011
Сообщений: 6
03.10.2011, 16:02  [ТС] #6
Да вроде бы он в теле цикла... А куда его нужно перенести, чтобы он оказался в теле цикла?
0
Ksana_
92 / 46 / 8
Регистрация: 11.02.2010
Сообщений: 187
03.10.2011, 16:05 #7
цикл for срабатывает только на один оператор, который следует за ним, если он не заключен в логические скобки begin end, проследите , какой end относится к какому begin, и увидите, куда стоит вставить этот оператор
0
Andbiz
0 / 0 / 0
Регистрация: 03.10.2011
Сообщений: 6
03.10.2011, 16:09  [ТС] #8
Цитата Сообщение от Dzhej-Dzhej Посмотреть сообщение
ln(-1) - вот это непонятно.
(i+j)*ln(-1) -это -1^(i+j). Вроде бы так записывается степень. При нахождении элементов обратимой матрицы они рассчитываются по формуле (-1^(i+j)*алгебраическое дополнение)/определитель исходной матрицы.

Добавлено через 3 минуты
Переместил вот так - все равно ошибка "Invalid floating point operation" на строке "C[i,j]:=((i+j)*ln(-1)*det_1)/det;

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
begin
                                   det_1:=1.0;
                                   // начинаю прямой ход Гаусса
                                   for k:=1 to n-1 do
                                   begin
                                        det_1:=det_1*D[k,k];  //вычисление определителя
                                        for j:=k+1 to n-1 do
                                        begin
                                             D[k,j]:=D[k,j]/D[k,k];
                                        end;
                                        for i:=k+1 to n-1 do  //начало вложенного цикла
                                        for j:=k+1 to m-1 do
                                        begin
                                             r:=D[k,j]*D[i,k];
                                             D[i,j]:=D[i,j]-r;
                                        end;
                                        C[i,j]:=((i+j)*ln(-1)*det_1)/det; // рассчитываю соответствующий элемент матрицы С
                                        StringGrid_C.Cells[j-1,i-1]:=FloatToStr(C[i,j])  // вношу рассчитанный элемент в матрицу
                                   end;
 
                              end;
0
Dzhej-Dzhej
Заблокирован
03.10.2011, 16:26 #9
может все же Power(-1, i + j); или IntPower(-1, i + j);(Модуль: Math) ,а то ln(-1) не определено и непонятно откуда логарифм на пустом месте.

Добавлено через 11 минут
для положительного х можно было бы записать у в степени х = exp(y*ln(x))
0
Andbiz
0 / 0 / 0
Регистрация: 03.10.2011
Сообщений: 6
03.10.2011, 16:27  [ТС] #10
Цитата Сообщение от Dzhej-Dzhej Посмотреть сообщение
может все же Power(-1, i + j); или IntPower(-1, i + j);(Модуль: Math) ,а то ln(-1) не определено и непонятно откуда логарифм на пустом месте.
Да, точно. Я тут ошибся - логарифма от -1 нет. Возвел в степень через Power. Теперь при попытке вычисления обратной матрицы 3*3 в результирующей матрице заполняется числом только элемент с индексом [3,3], все остальные без изменения. Да и то число, которое ставится - неверное (к примеру нужно 1, а программа ставит -3).
0
Kridan
65 / 65 / 1
Регистрация: 08.10.2010
Сообщений: 138
03.10.2011, 19:41 #11
Цитата Сообщение от Ksana_ Посмотреть сообщение
StringGrid_C.Cells[j-1,i-1]:=FloatToStr(C[i,j]) // вношу рассчитанный элемент в матрицу end;
Запись результата в таблицу тоже в тело цикла внеси.
0
Andbiz
0 / 0 / 0
Регистрация: 03.10.2011
Сообщений: 6
03.10.2011, 22:24  [ТС] #12
Цитата Сообщение от Kridan Посмотреть сообщение
Запись результата в таблицу тоже в тело цикла внеси.
Не соображу. Проверяю отладчиком - как будто-то бы в цикле. Напишите пожалуйста, куда именно его нужно переместить.

Подредактировал программу. Сейчас ее код имеет следующий вид:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
                        begin
                         det:=1;
                         // начинаю прямой ход Гаусса
                         for k:=1 to n do
                         begin
                              det:=det*A[k,k]; //вычисление определителя
                              for j:=k+1 to n do
                              begin
                                   A[k,j]:=A[k,j]/A[k,k];
                              end;
                              for i:=k+1 to n do //начало вложенного цикла
                              for j:=k+1 to m do
                              begin
                              r:=A[k,j]*A[i,k];
                              A[i,j]:=A[i,j]-r;
                              end;
                         end;
                         Edit1.Text:=FloatToStr(det);
                         // Создаю союзную матрицу D
                         begin
                              for i:=1 to n do  // начинаю цикл обхода всех строк и столбиков матрицы А
                              for j:=1 to m do
                              begin
                                   l:=1;
                                   p:=1;
                                   for i_1:=1 to n do // начинаю второй цикл обхода матрицы А, в котором будут отсеиваться одна строчка и один столбик
                                   for j_1:=1 to m do
                                       if (i_1<>i) and (j_1<>j)  // отсеиваю элементы, которые находятся в столбике или строчке рассматриваемого элемента матрицы
                                       then
                                           begin
                                           D[l,p]:=A[i_1,j_1]; // вношу соответствующий элемент в временную матрицу D
                                           p:=p+1;  // прибавляю 1 к индексу столбика матрицы D
                                           if(p>(m-1)) // проверяю индекс столбика на крайнее значение, если оно больше (n-1) исходной таблицы, то перехожу на новую строку
                                           then
                                           begin
                                           p:=1;  // при начале новой строки столбик приравниваю единице
                                           l:=l+1;  // и на одну строчку опускаюсь вниз, прибавив к l единицу
                                           end;
                                           end;
                                               begin
                                               if (n-1)=1 then det_1:=D[1,1]  // если матрица еденичная, то определитель определить легком
                                               else
                                               if (n-1)=2 then det_1:=(D[1,1]*D[2,2]-D[1,2]*D[2,1])  // если матрица имеет размерность 2*2, то определитель можно найти по следующей формуле
                                               else
                                                    begin
                                                    det_1:=1;
                                                    // начинаю прямой ход Гаусса
                                                    for k:=1 to n-1 do
                                                        begin
                                                        det_1:=det_1*D[k,k];  //вычисление определителя
                                                        for p:=k+1 to n-1 do
                                                            begin
                                                                 D[k,p]:=D[k,p]/D[k,k];
                                                            end;
                                                            for l:=k+1 to n-1 do  //начало вложенного цикла
                                                            for p:=k+1 to m-1 do
                                                            begin
                                                                 r:=D[k,p]*D[l,k];
                                                                 D[l,p]:=D[l,p]-r;
                                                            end;
                                                        end;
                                                    end;
                                                        C[i,j]:=(power((-1),(i+j))*det_1)/det; // рассчитываю соответствующий элемент матрицы С
                                                        StringGrid_C.Cells[i-1,j-1]:=FloatToStr(C[i,j])  // вношу рассчитанный элемент в матрицу
                                               end;
Сейчас программа считает обратную матрицу неверно. Во вложении привожу пример расчета. Определитель исходной матрицы рассчитан верно, а вот сама обратная матрица - неверно. Слева в окне расчет программы, а справа - правильный расчет.

Что может быть еще не правильно?
0
Миниатюры
Ошибка "Invalid floating point operation" при расчете обратной матрицы  
03.10.2011, 22:24
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.10.2011, 22:24
Привет! Вот еще темы с ответами:

У меня ошибки при нажатии на выполнение выводит "invalid floating point operation" - Delphi
Здравствуйте, не могли бы помочь мне. У меня ошибки при нажатии на выполнение выводит &quot;invalid floating point operation&quot; Код...

"invalid floating point operation" в Delphi - Delphi
Привет!:) Ребят, подскажите, пожалуйста, где я в упор не вижу ошибку? Нужно было написать програмку для решения системы линейных...

Ошибка при запуске прогрммы на windows 8 invalid floating point operation - Delphi
Здраствуйте. Такая проблема разрабатывал программу в делфи 7 на виндовс 7. На виндовс 7 все работает исправно, не только на компьютере...

Ошибка invalid floating point operation в Delphi при реализации фильтра Собеля - Delphi
Помогите разобраться, в чем ошибка при реализации фильтра Собеля var Form1: TForm1; c:TColor; r,g,b:byte; My:array of integer;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru