Форум программистов, компьютерный форум, киберфорум
Free Pascal
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 28.05.2017
Сообщений: 7

Ошибки 201/216 при попытке перемножить динамические массивы

28.01.2019, 17:37. Показов 2278. Ответов 17

Студворк — интернет-сервис помощи студентам
Добрый вечер,
решаю задачу такого характера: нужно из матрицы А получить матрицу В = А + А2 + ... + Аn. Натуральное число n и порядок матрицы вводятся с клавиатуры.
С выделением памяти, заполнением матрицы, ее выводом, а так же со сложением проблем нет - программа все считает и выводит. Как только начала тестить умножение - при запуске после ввода А выскакивают ошибки 201, 216.
С чем это может быть связано, и как это исправить? Динамические структуры только начали проходить, и пока не все понятно

Pascal
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
program lab14;
 
 
type
  p = ^integer;
  pp = ^p;
var
  a, b, c : pp;
  m, i    : integer;
  n       : byte;
 
procedure add_memory(var a : pp; m : integer);
var i, j : integer;
  begin
    GetMem(a, m*sizeof(integer));
      for i:=0 to m-1 do
        for j:=0 to m-1 do
          GetMem(a[i], m*sizeof(integer));
  end;
 
procedure random_input(var a: pp; m : integer);
var i, j : integer;
  begin
    randomize;
    for i:=0 to m-1 do
      for j:=0 to m-1 do
        a[i, j]:=random(10);
  end;
 
procedure output_matr(a : pp; m : integer);
var i, j : integer;
  begin
    for i:=0 to m-1 do
      begin
        for j:=0 to m-1 do
          write(a[i, j]:4);
        writeln();
      end;
  end;
 
procedure summ_matr(a, b : pp; var c : pp; m : integer);
var i, j : integer;
  begin
    for i:=0 to m-1 do
      for j:=0 to m-1 do
        c[i, j]:=a[i, j] + b[i, j];
  end;
 
procedure mult_matr(a, b : pp; var c : integer; m : integer);
var i, j, k, s : integer;
  begin
   for i:=0 to m-1 do
     for j:=0 to m-1 do
       begin
         s:=0;
         for k:=0 to m-1 do
           s:=s + a[i, k]*b[k, j];
         c[i, j]:=s;
        end;
  end;
 
procedure clearmemory(a : pp; m : integer);
var i : integer;
  begin
    for i:=0 to m-1 do
      FreeMem(a[i]);
    FreeMem(a);
  end;
 
 
  begin
    write('Введите n = ');
    readln(n);
    writeln();
 
    write('Введите порядок матрицы А = ');
    readln(m);
    writeln();
 
    // выделение памяти для А, B, C
    add_memory(a, m);
    add_memory(b, m);
    add_memory(c, m);
 
    // заполнение А случайными числами
    random_input(a, m);
 
    writeln('Матрица А: ');
    output_matr(a, m);
 
    b:=a; c:=a;
 
    for i:=2 to n do
      begin
        mult_matr(a, c, c, m);
        summ_matr(c, b, b, m);
      end; 
   
 
    // вывод матрицы В
    writeln();
    writeln('Матрица В: ');
    output_matr(b, m);
 
 
    // освобождение памяти
    clearmemory(a, m);
    clearmemory(b, m);
    clearmemory(c, m);
 
    readln();
  end.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.01.2019, 17:37
Ответы с готовыми решениями:

Как обойти системные ошибки 106 и 201 при поиске
Помогите найти выход из ситуации. Есть прога, выполняющая банальный поиск. Как обойти системные ошибки 106 и 201? т.е. нужно...

Код ошибки 201. Тип переменных менял, все одно ошибка при исполнении программы
program maximini; uses crt; var mas:array of integer; x,j,min,max:integer; i:byte; BEGIN randomize; for i:=1 to 10 do ...

Графика, ошибки 216/217
Почему pascal ругается и выдает ошибки 216/217 ПАМАГИТЕ program aa; uses graph,crt; var c,a,b:integer; begin setcolor(4); ...

17
 Аватар для vlisp
1067 / 988 / 153
Регистрация: 10.08.2015
Сообщений: 5,394
01.02.2019, 00:04
Цитата Сообщение от burgundel Посмотреть сообщение
pp = ^p;
Ты неправильно назвал тип данных. Компилятор не знает, что это матрица и не может ее умножить.
попробуй использовать функции вместо процедур. например, написать функцию возведения матрицы в степень.
И не нужно называть матрицу числом, они от этого грустят
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7818 / 4637 / 2837
Регистрация: 22.11.2013
Сообщений: 13,159
Записей в блоге: 1
01.02.2019, 00:33
https://www.cyberforum.ru/post13171411.html

Добавлено через 12 минут
Цитата Сообщение от vlisp Посмотреть сообщение
Компилятор не знает, что это матрица и не может ее умножить.
Это ошибочное утверждение.
Ошибки немного в другом.

Pascal
14
15
16
17
18
begin
  GetMem(a,m*SizeOf(a^));
  for i:=0 to m-1 do
    GetMem(a[i],m-1*SizeOf(a[i]^));
end;
burgundel,
но лучше использовать динамические массивы, раз уж они есть в языке:
Pascal
1
2
3
4
5
6
type TMatrix = array of array of Integer;
 
var
  a, b, c: TMatrix;
...
  SetLength(a,m,m); SetLength(b,m,m); SetLength(c,m,m);
Добавлено через 3 минуты
burgundel,
Pascal
91
    b:=a; c:=a;
так дело не пойдёт. Вы назначили указатели туда, куда указывал a, память, выделенная под b, c потерялась. Скорее всего хотели продублировать содержимое массивов -- тогда нужно копировать поэлементно.

Для динамических массивов вам в этом поможет Copy().
0
 Аватар для vlisp
1067 / 988 / 153
Регистрация: 10.08.2015
Сообщений: 5,394
01.02.2019, 15:29
Цитата Сообщение от bormant Посмотреть сообщение
Это ошибочное утверждение.
Ошибочно утверждение, что мое утверждение ошибочно
Ведь как вы лодку назовете, так она и поплывет. Не говоря уж о подводных камнях указателей
Код должен быть понятен, тогда его легче дебажить. Код ниже не идеален, но он хотя бы работает
Pascal
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
program lab14;
 
type
  p = ^Integer;
  pp = ^p;
var
  a, b, c : pp;
  n, m, i : byte;
 
function create_matr(m : byte) : pp;
var i : byte;
    a : pp;
  begin
    a:=nil;
    GetMem(a, m*sizeof(a^));
      for i:=0 to m-1 do
          GetMem(a[i], m*sizeof(a[i]^));
 
    result := a;
end;
 
procedure delete_matr(a : pp; m : byte);
var i : byte;
  begin
    for i:=0 to m-1 do
      FreeMem(a[i]);
    FreeMem(a);
  end;
 
procedure fill_random_matr(a : pp; m : byte);
var i, j : byte;
begin
    Randomize;
    for i:=0 to m-1 do
      for j:=0 to m-1 do
        a[i,j]:= random(10);
end;
// Процедура копирования матрицы нужна для избежания накопительной погрешности
// при умножении матриц
procedure copy_matr(a : pp; var b:pp; m : byte);
var i, j : byte;
begin
 
    for i:=0 to m-1 do
      for j:=0 to m-1 do
        b[i,j]:= a[i,j];
end;
 
procedure summ_matr(a, b : pp; var c : pp; m : byte);
var i, j : byte;
  begin
    for i:=0 to m-1 do
      for j:=0 to m-1 do
        c[i, j]:=a[i, j] + b[i, j];
  end;
 
procedure mult_matr( a, b : pp; var c : pp; m : byte);
var i, j, k, s : byte;
    d, e : pp;
  begin
    d := create_matr(m);
    e := create_matr(m);
    copy_matr(a,d,m);
    copy_matr(b,e,m);
   for i:=0 to m-1 do
     for j:=0 to m-1 do
       begin
         s:=0;
         for k:=0 to m-1 do
           s:=s + d[i, k]*e[k, j];
         c[i, j]:=s;
        end;
   delete_matr(d,m);
   delete_matr(e,m);
  end;
 
procedure pow_matr(a : pp; var b : pp; n, m : byte);
var i : byte;
begin
   copy_matr(a,b,m);
   For i:=2 to n do
     begin
      mult_matr(a,b,b,m);
    end;
end;
 
procedure output_matr(a : pp; m : byte);
var i, j : integer;
  begin
 
    for i:=0 to m-1 do
      begin
        Write(a[i, 0]);
        for j:=1 to m-1 do
          Write(a[i, j]:16);
        writeln();
      end;
  end;
 
begin
    write('Введите максимальную степень матрицы n = ');
    readln(n);
    writeln();
 
    write('Введите порядок матрицы А = ');
    readln(m);
 
    a := create_matr(m);
    b := create_matr(m);
    c := create_matr(m);
 
    fill_random_matr(a,m);
 
 
    copy_matr(a,c,m);
    copy_matr(a,b,m);
 
     // без проверки n
 
    for i := 2 to n do
      begin
         mult_matr(b,a,b,m);
         summ_matr(c,b,c,m);
      end;
 
    writeln;
    output_matr(c,m);
 
    delete_matr(a,m);
    delete_matr(b,m);
    delete_matr(c,m);
 
    readln();
  end.
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7818 / 4637 / 2837
Регистрация: 22.11.2013
Сообщений: 13,159
Записей в блоге: 1
01.02.2019, 16:50
Цитата Сообщение от vlisp Посмотреть сообщение
Код ниже не идеален
Ну и чем это лучше SetLength() плюс помянутого выше https://www.cyberforum.ru/post13171411.html ?
0
 Аватар для vlisp
1067 / 988 / 153
Регистрация: 10.08.2015
Сообщений: 5,394
02.02.2019, 20:38
Цитата Сообщение от bormant Посмотреть сообщение
Ну и чем это лучше SetLength()
ну, это как прийти на бал зубных фей в костюме усманова
этот пример показывает, что не все так гладко при использовании указателей. а ваш пример не оформлен должным образом.
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7818 / 4637 / 2837
Регистрация: 22.11.2013
Сообщений: 13,159
Записей в блоге: 1
03.02.2019, 15:45
vlisp,
про бал не понял, ну да ладно...
про "не оформлен" -- что там оформлять-то?
1) заменить строку 5 на
Pascal
5
  TMatrix = array [1..nMax,1..nMax] of TFloat;
2) дописать генерацию по аналогии с mRead или заменить mRead:
Pascal
22
23
24
25
26
procedure mGen(var a: TMatrix; n: Integer);
var i, j: Integer;
begin
  for i:=0 to n-1 do for j:=0 to n-1 do a[i,j]:=Random(10);
end;
3) в mMul добавить
Pascal
16
  SetLength(t,n,n);
4) в строке 43 заменить ввод на генерацию:
Pascal
43
  SetLength(a,m,m); mGen(a,m);
и исправить присваивание копий:
Pascal
45
  b:=Copy(a); t:=Copy(a);
5) заменить циклы от 0 до n-1. Для эстетствующих, можно убрать из параметров размерность матрицы, заменив верхние границы циклов на Length(a)-1 и Length(a[i])-1 соответственно.
6) если зачем-то очень хочется очистить память руками:
Pascal
50
  SetLength(a,0); SetLength(b,0); SetLength(t,0);
7) если нужны были целые,
Pascal
4
  TFloat = Longint;
и в выводе (Write) заменить ":W:D" на ":W."

Собственно, вот и вся разница.

Вся эта тривиальщина -- точно не "космические технологии".

Добавлено через 9 минут
Если наложить ограничение на то, что в mMul() фактический параметр r не может быть одним из фактических a, b, то можно убрать промежуточную матрицу t и распределение памяти под нее, сразу заполнять r.
0
 Аватар для vlisp
1067 / 988 / 153
Регистрация: 10.08.2015
Сообщений: 5,394
03.02.2019, 16:39
Цитата Сообщение от bormant Посмотреть сообщение
про бал не понял, ну да ладно...
Да вот не ладно. Тут тема про указатели, олдскульный треш, пришедший из щей под дос. а у вас динамические массивы. И стоила б овчинка выделки, можно было б потестить производительность, но в данном случае это не имеет смысла, так как матрицы "растут" очень быстро и вываливаются за пределы целых раньше, чем могла бы возникнуть разница по времени двух вариантов.

Есть такое явление, когда человек просит помощи в одном, а ему взамен предлагают другое и не факт, что это другое ему нужно. Вот вам и бал.


Вы вероятно предполагали, что ваш код будут просто копировать в свой.. Но лучше оформить код в виде модуля. Написать комментарии, отформатировать код, чтоб он был читаемым, вставить копирайт. и приложить файл модуля для скачивания.
Вот это я называю правильно оформленный код.
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7818 / 4637 / 2837
Регистрация: 22.11.2013
Сообщений: 13,159
Записей в блоге: 1
03.02.2019, 18:34
Цитата Сообщение от vlisp Посмотреть сообщение
олдскульный треш, пришедший из щей под дос. а у вас динамические массивы
Олдскульный треш тоже бывает разный. Навскидку пара вариантов: 1) как здесь, 2) одним куском.
Плюсы (1): синтаксис FPC позволяет обращаться к указателю как к массиву, поэтому вместо
a[i]^[j] имеем вполне себе обычное a[i][j] или a[i,j]. Минусы (1): громоздкое создание/удаление.
Плюсы (2): создание/удаление/копирование тривиальны. Минусы (2): адресация в виде a[i*n+j], тем не менее, последовательное обращение к элементам как построчно так и поколоночно поддается некоторой оптимизации.

Цитата Сообщение от vlisp Посмотреть сообщение
Есть такое явление, когда человек просит помощи в одном, а ему взамен предлагают другое и не факт, что это другое ему нужно.
У каждой монеты более одной стороны: бывает часто, что человек не знает, что ему нужно, но просит помощи в том как он сам видит решение, а на самом деле нужно ему совсем-совсем другое.

Цитата Сообщение от vlisp Посмотреть сообщение
Но лучше оформить код в виде модуля. Написать комментарии, ..., вставить копирайт. и приложить файл модуля для скачивания.
Вот это я называю правильно оформленный код.
Как минимум забыли комплект документации на модуль, покрытие тестами. Какой же без них правильно оформленный?
И да, дописать unit SomeShit; interface, imlementation, end.,uses SomeShit; -- непосильная задача

Добавлено через 18 минут
Цитата Сообщение от vlisp Посмотреть сообщение
Код ниже не идеален
К слову, зачем бы были нужны строки 61-64, 73-74, многовато распределений/удалений, одной пары было бы достаточно.

Добавлено через 55 минут
Ах да, Randomize внутри fill_random_matr() -- идея не очень хорошая, если не сказать хуже.
0
 Аватар для vlisp
1067 / 988 / 153
Регистрация: 10.08.2015
Сообщений: 5,394
04.02.2019, 01:00
Цитата Сообщение от bormant Посмотреть сообщение
И да, дописать
так код пишется не для того, чтоб его дописывали
Цитата Сообщение от bormant Посмотреть сообщение
К слову, зачем бы были нужны строки 61-64, 73-74, многовато распределений/удалений, одной пары было бы достаточно.
пожалуй вы правы, достаточно создать одну временную временную матрицу
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
procedure mult_matr( a, b : pp; var c : pp; m : byte);
var i, j, k, s : byte;
    d, e : pp;
begin
   d := create_matr(m);
   for i:=0 to m-1 do
     for j:=0 to m-1 do
       begin
         s:=0;
         for k:=0 to m-1 do
           s:=s + a[i, k]*a[k, j];
         d[i, j]:=s;
        end;
   copy_matr(d,c,m);
   delete_matr(d,m);
end;
впрочем ТС похоже уже все равно
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7818 / 4637 / 2837
Регистрация: 22.11.2013
Сообщений: 13,159
Записей в блоге: 1
04.02.2019, 13:32
vlisp,
в новой mult_matr временной матрицы действительно достаточно, кроме того, можно легко обойтись без копирования содержимого, достаточно копирования одного указателя:
Pascal
14
15
  if (c<>a) and (c<>b) then delete_matr(c);
  c:=d;
а можно предусмотреть случай без создания временной матрицы, когда она не нужна:
Pascal
5
6
7
8
9
  if (c<>a) and (c<>b) then d:=c else d:=create_matr(m);
...
  if (d<>c) then begin
    delete_matr(c); c:=d;
  end;
0
 Аватар для vlisp
1067 / 988 / 153
Регистрация: 10.08.2015
Сообщений: 5,394
04.02.2019, 15:07
нет, что-то не получается, заметил очепятку вместо a[j,k] Нужно b [j,k]. но результат все равно неверный

Pascal
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
program lab14;
 
 
type
  p = ^Integer;
  pp = ^p;
var
  a, b, c : pp;
  n, m, i : byte;
 
function create_matr(m : integer) : pp;
var i : integer;
    a : pp;
  begin
    a:=nil;
    GetMem(a, m*sizeof(a^));
      for i:=0 to m-1 do
          GetMem(a[i], m*sizeof(a[i]^));
 
    result := a;
end;
 
procedure delete_matr(a : pp; m : integer);
var i : int64;
  begin
    for i:=0 to m-1 do
      FreeMem(a[i]);
    FreeMem(a);
  end;
 
procedure fill_random_matr(a : pp; m : integer);
var i, j : integer;
begin
    //Randomize;
    for i:=0 to m-1 do
      for j:=0 to m-1 do
        a[i,j]:= random(10);
end;
// Процедура копирования матрицы нужна для избежания накопительной погрешности
// при умножении матриц
procedure copy_matr(a : pp; var b:pp; m : integer);
var i, j : integer;
begin
 
    for i:=0 to m-1 do
      for j:=0 to m-1 do
        b[i,j]:= a[i,j];
end;
 
procedure summ_matr(a, b : pp; var c : pp; m : integer);
var i, j : integer;
  begin
    for i:=0 to m-1 do
      for j:=0 to m-1 do
        c[i, j]:=a[i, j] + b[i, j];
  end;
 
procedure mult_matr(const a, b : pp; var c : pp; m : integer);
// этот вариант считает правильно
var i, j, k, s : integer;
    d, e : pp;
  begin
    d := create_matr(m);
    e := create_matr(m);
    copy_matr(a,d,m);
    copy_matr(b,e,m);
   for i:=0 to m-1 do
     for j:=0 to m-1 do
       begin
         s:=0;
         for k:=0 to m-1 do
           s:=s + d[i, k]*e[k, j];
         c[i, j]:=s;
        end;
   delete_matr(d,m);
   delete_matr(e,m);
  end;
 { }
 
procedure mult_matr( a, b : pp; var c : pp; m : byte);
// этот вариант считает неправильно
var i, j, k, s : byte;
    d, e : pp;
begin
   d := create_matr(m);
   for i:=0 to m-1 do
     for j:=0 to m-1 do
       begin
         s:=0;
         for k:=0 to m-1 do
           s:=s + a[i, k]*b[k, j];
         d[i, j]:=s;
        end;
  // copy_matr(d,c,m);
  // delete_matr(d,m);
     delete_matr(c,m);
     c:=d;
end;
 
 
procedure pow_matr(const a : pp; var b : pp; n, m : integer);
var i : integer;
begin
   copy_matr(a,b,m);
   For i:=2 to n do
     begin
      mult_matr(a,b,b,m);
    end;
end;
 
procedure output_matr(a : pp; m : integer);
var i, j : integer;
  begin
 
    for i:=0 to m-1 do
      begin
        Write(a[i, 0]);
        for j:=1 to m-1 do
          Write(a[i, j]:16);
        writeln();
      end;
  end;
 
begin
    write('Введите максимальную степень матрицы n = ');
    readln(n);
    writeln();
 
    write('Введите порядок матрицы А = ');
    readln(m);
 
    a := create_matr(m);
    b := create_matr(m);
    c := create_matr(m);
 
    fill_random_matr(a,m);
 
    writeln;
    output_matr(a,m);
     {
    mult_matr(a,a,a,m);
    writeln;
    output_matr(a,m);
    readln;   }
 
    copy_matr(a,c,m);
    copy_matr(a,b,m);
 
 
 
    for i := 2 to n do
      begin
         mult_matr(a,b,b,m);
         summ_matr(c,b,c,m);
      end;
 
    writeln;
    output_matr(c,m);
 
    delete_matr(a,m);
    delete_matr(b,m);
    delete_matr(c,m);
 
    readln();
  end.
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7818 / 4637 / 2837
Регистрация: 22.11.2013
Сообщений: 13,159
Записей в блоге: 1
04.02.2019, 17:52
Pascal
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
const nMax=10; W=8; D=0;
type
  TElement = Double;
  PElement = ^TElement;
  TMatrix = ^PElement;
 
procedure mCreate(var a: TMatrix; n: Integer);
var i: Integer;
begin
  GetMem(a,n*SizeOf(a^)); for i:=0 to n-1 do GetMem(a[i],n*SizeOf(a^^));
end;
 
procedure mFree(a: TMatrix; n: Integer);
var i: Integer;
begin
  for i:=n-1 downto 0 do FreeMem(a[i]); FreeMem(a);
end;
 
procedure mCopy(a, b: TMatrix; n: Integer);
var i: Integer;
begin
  for i:=0 to n-1 do Move(a[i]^,b[i]^,n*SizeOf(a^^));
end;
 
procedure mGen(a: TMatrix; n: Integer);
var i, j: Integer;
begin
  for i:=0 to n-1 do for j:=0 to n-1 do a[i,j]:=Random(10);
end;
 
procedure mWrite(a: TMatrix; n: Integer; p: String);
var i, j: Integer;
begin
  WriteLn(p);
  for i:=0 to n-1 do begin
    for j:=0 to n-1 do Write(a[i,j] :W:D); WriteLn;
  end;
end;
Pascal
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
procedure mAdd(a, b: TMatrix; r: TMatrix; n: Integer);
var i, j: Integer;
begin
  for i:=0 to n-1 do for j:=0 to n-1 do r[i,j]:=a[i,j]+b[i,j];
end;
 
procedure mMul(a, b: TMatrix; var r: TMatrix; n: Integer);
var i, j, k: Integer; t: TMatrix; s: TElement;
begin
  if (r<>b) and (r<>a) then t:=r else mCreate(t,n);
  for i:=0 to n-1 do for j:=0 to n-1 do begin
    s:=0; for k:=0 to n-1 do s:=s+a[i,k]*b[k,j]; t[i,j]:=s;
  end;
  if t<>r then begin
    mFree(r,n); r:=t;
  end;
end;
 
var
  a, b, t: TMatrix;
  m, n: Integer;
begin
  Randomize;
  repeat Write('Размер матрицы [2..',nMax,']: '); Read(m);
  until m in [2..nMax];
  Write('n: '); ReadLn(n);
  mCreate(a,m); mCreate(b,m); mCreate(t,m);
  mGen(a,m); mCopy(a,b,m); mCopy(a,t,m);
  for n:=2 to n do begin
    mMul(a,t,t,m); mAdd(t,b,b,m);
  end;
  mWrite(a,m,'A ='); mWrite(b,m,'B =');
  mFree(a,m); mFree(b,m); mFree(t,m);
end.
Добавлено через 15 секунд
vlisp,
проверяйте.
0
 Аватар для vlisp
1067 / 988 / 153
Регистрация: 10.08.2015
Сообщений: 5,394
04.02.2019, 23:29
опять вы со своими массивами... ну, поймите это мне не интересно, мне интересно понять почему не работает код, который по идее должен работать
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7818 / 4637 / 2837
Регистрация: 22.11.2013
Сообщений: 13,159
Записей в блоге: 1
05.02.2019, 02:17
vlisp,
почему своими, с кривыми динамическими по двойному GetMem/FreeMem, все ровно как просили
Найдете и проанализируете отличия — выясните источник ошибки...

Добавлено через 6 минут
Для сверки расчетов можно вместо Randomize задавать в начале одинаковый RandSeed, генерируемые последовательности будут воспроизводимыми.
0
 Аватар для vlisp
1067 / 988 / 153
Регистрация: 10.08.2015
Сообщений: 5,394
05.02.2019, 02:38
проблема в том, что процедура mult_matr в обоих случаях умножает матрицу правильно, а в итоге, получается разный результат. причем если создавать 1 временную матрицу, то результат меньше, подозреваю, где-то неинициализированная матрица с нулями перемножается, но где - непонятно. какой-то для меня неуловимый побочный эффект, которого нет, когда создаешь 2 матрицы (1 вариант)
чет у меня ваши имена процедур, ассоциировались с массивами...
у вас то же самое, что и у меня, только имена другие, разве не так? вы проверяли свой код на правильность вычислений?
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7818 / 4637 / 2837
Регистрация: 22.11.2013
Сообщений: 13,159
Записей в блоге: 1
05.02.2019, 09:22
Цитата Сообщение от vlisp Посмотреть сообщение
причем если создавать 1 временную матрицу, то результат меньше, подозреваю, где-то неинициализированная матрица с нулями перемножается, но где - непонятно
Подозрение ваше неверное.
Действительная причина проста и весьма прозаична -- маловат аккумулятор суммы:
Pascal
82
var ... s : byte;
1
 Аватар для vlisp
1067 / 988 / 153
Регистрация: 10.08.2015
Сообщений: 5,394
05.02.2019, 11:05
Цитата Сообщение от bormant Посмотреть сообщение
маловат аккумулятор суммы:
чьорт
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.02.2019, 11:05
Помогаю со студенческими работами здесь

Free pascal выдает в проге на Динамические переменные ошибку exicode 201, Как исправить?
Задача такая: Даны две прямоугольные матрицы А и В. Определить верно ли что А=В(транспонированная). Решение думаю правильное, может...

Ошибки при попытке подключения к MySQL
Для подключения использую библиотеки Oracle, (mysql-connector-net-6.9.6.msi) формирую сроку подключения string conn = &quot;Data...

При попытке запустить ВПН выдаются ошибки
Добрый день. При попытке запустить ВПН в Windows 8 выдаются такие ошибки: 1) error 720 2) error 809 Вложила картинки с...

Ошибки при попытке прочитать в указанном месте
#include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;locale&gt; using namespace std; struct stack { char c; struct stack...

Вылетает программа при попытке вывести массивы
Долго не могу понять, в чём проблема, поэтому обращаюсь к вам. Я пробовал в main.c временно изъять функции вывода, и программа вроде...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru