![]() |
Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.
![]() |
P-Tigr |
![]() ![]()
Сообщение
#1
|
Группа: Пользователи Сообщений: 9 Пол: Мужской Репутация: ![]() ![]() ![]() |
Столкнулся с одной проблемой, 2 дня уже бьюсь... что делать - не знаю...
Если коротко, то дело вот в чем. Я написал процедуру для подсчета определителя матрицы любого порядка (методом Гаусса). И там над матрицей выполняются различные преобразования (складывания строк и т.д.). Причем - внимание - по условию задания матрица должна быть обязательно динамической! Процедура работает нормально, определитель находит, НО в то же время изменяет исходную матрицу, а этого нельзя допустить!! Происходит это, как мне кажется, из-за того, что такие матрицы - ссылки на память, поэтому передать ее в процедуру строго по значению нельзя... Замучился я с этими динамическими структурами... ![]() Please, умные люди, help me! |
![]() ![]() |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
P-Tigr, давайте так: вы можете показать код процедуры? тогда покажите, как именно вы работаете с матрицей, и можно будет сказать, как избежать ее изменения. Теоретически (не зная деталей реализации) очень трудно давать советы...
|
P-Tigr |
![]()
Сообщение
#3
|
Группа: Пользователи Сообщений: 9 Пол: Мужской Репутация: ![]() ![]() ![]() |
Вот выдержки из кода:
typeвроде все... здесь А - исходная матрица В - полученная |
P-Tigr |
![]()
Сообщение
#4
|
Группа: Пользователи Сообщений: 9 Пол: Мужской Репутация: ![]() ![]() ![]() |
Причем кроме вышеописанной проблемы, при данных допустим
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 генерируется странная ошибка - "Floating operation error" |
volvo |
![]()
Сообщение
#5
|
Гость ![]() |
Компилятор какой? Delphi или FPC? Турбо-Паскаль открытые массивы не поддерживает.
|
P-Tigr |
![]()
Сообщение
#6
|
Группа: Пользователи Сообщений: 9 Пол: Мужской Репутация: ![]() ![]() ![]() |
Естессно, Delphi ver 6
|
volvo |
![]()
Сообщение
#7
|
Гость ![]() |
Естественно, что я переношу тему в раздел Дельфи
![]() |
P-Tigr |
![]()
Сообщение
#8
|
Группа: Пользователи Сообщений: 9 Пол: Мужской Репутация: ![]() ![]() ![]() |
:D Just OK. I'm sorry, первый раз на форуме...
|
P-Tigr |
![]()
Сообщение
#9
|
Группа: Пользователи Сообщений: 9 Пол: Мужской Репутация: ![]() ![]() ![]() |
Thanks, Volvo!
|
volvo |
![]()
Сообщение
#10
|
Гость ![]() |
Значит, предложение такое: при входе в функцию вычисления определителя ты не присваиваешь адрес массива A в AC (как это происходит сейчас, а копируешь массив A в AC полностью и работаешь с его копией). Копирование производишь так:
setlength(ac, length(a));И не забудь убрать строки AC:=A;иначе все копирование будет лишено смысла ![]() я только что прогнал этот вариант - исходный массив не меняется (правда я не использовал процедуру Work_Matr, а проверил только вычисление определителя...) |
P-Tigr |
![]()
Сообщение
#11
|
Группа: Пользователи Сообщений: 9 Пол: Мужской Репутация: ![]() ![]() ![]() |
Извините пожалуйста, еще 1 вопрос, помогите разобраться!
Почему при вводе некоторых данных, например 1 1 1 1 1 1 1 1 1 в блоке функции нахождения определителя: for j:=0 to high(AC)-1 doв строке mnoj:=mn1/mn2; появляется ошибка, связанная с плавающей запятой: "Invalid floating point operation" или "Floating divizion by zero". ПОЧЕМУ? P.S.1. Ошибка появляется и при вводе разных чисел, но правда не всегда - очень странно... P.S.2. Я присоединил к письму exe-файл в rar-архиве - чтоб удобней было тестировать. Прикрепленные файлы ![]() |
volvo |
![]()
Сообщение
#12
|
Гость ![]() |
Цитата(P-Tigr @ 16.03.05 5:23) появляется ошибка, связанная с плавающей запятой: Это не связано с вводимыми данными... Только с тем, что у тебя в отмеченных строках просто напросто происходит выход за границы массива (не забывай, что динамические массивы индексируются с 0 до N-1), и кто знает, какие значения там хранятся... "Invalid floating point operation" или "Floating divizion by zero". ПОЧЕМУ? for j:=0 to high(AC)-1 doЯ совсем забыл написать, что я менял границы индексов когда проверял... Привычка... P.S. Смотри и выше в тексте функции. Там тоже есть выход за пределы массива... |
volvo |
![]()
Сообщение
#13
|
Гость ![]() |
P-Tigr, небольшая поправочка:
Выход за пределы массива тут ни при чем... Сейчас еще раз прогнал твою программу... Вот посмотри на скриншот, который я сделал в определенный момент. Как ты думаешь, что произойдет на следующем шаге? Я думаю, что деление на 0... ![]() Это в принципе ясно, ведь если у тебя матрица: 1, 1, 1 1, 1, 1 1, 1, 1 то после вычитания первой строки из второй и из третьей, она становится такой: 1, 1, 1 0, 0, 0 0, 0, 0 и далее как только ты пытаешься найти множитель для вычитания 3-ей строки из второй - Oops ![]() Добавлено: Ну или вот так (взято из реализации trminator-а отсюда: Определитель матрицы ): function Opred_Gauss(A:TDMAtr):real; Эскизы прикрепленных изображений ![]() |
P-Tigr |
![]()
Сообщение
#14
|
Группа: Пользователи Сообщений: 9 Пол: Мужской Репутация: ![]() ![]() ![]() |
ОК, ошибка "Floating divizion by zero" устранена... Мне надо ставить 2 за внимательность...
![]() Но осталась 2-я ошибка - "Invalid floating point operation". Итак, код такой: function Opred_Gauss(A:TDMAtr):real; При данных 1 1 1 возникает вышеописанная ошибка в той же строке mnoj:=a[j,i]/a[i,i]; Немного помучившись и покапавшись в справочниках, нашел, что это бывает связано с проблемами сопроцессора, и устраняется путем добавления строчки asm FINIT end; тогда вместо ошибки возвращается константа NAN. Окончательный вариант кода выглядит так: function Opred_Gauss(A:TDMAtr):real;Вот теперь (!) все работает без ошибок... УРА! Но интересно, есть ли другие пути решения проблемы, без асмы? И отчего она все-таки, эта ошибка? |
volvo |
![]()
Сообщение
#15
|
Гость ![]() |
Цитата(P-Tigr @ 16.03.05 17:40) ОК, ошибка "Floating divizion by zero" устранена... Мне надо ставить 2 за внимательность... Вам надо еще раз поставить 2 за "внимательность"... Неужели нельзя было проверить все ли A заменены на AC? Ведь NaN появляется при той же самой ошибке - "деление на 0"... Почему? Проверяется на 0 значение AC, а операция производится с A !!!![]() Но осталась 2-я ошибка - "Invalid floating point operation". Итак, код такой: function Opred_Gauss(A:TDMAtr):real; В общем, окончательный вариант функции без всякого Асма: Function Opred_Gauss(A:TDMatr):double; |
P-Tigr |
![]()
Сообщение
#16
|
Группа: Пользователи Сообщений: 9 Пол: Мужской Репутация: ![]() ![]() ![]() |
Блин...
Спасибо за помощь! ![]() ![]() |
$ad!st |
![]()
Сообщение
#17
|
![]() Новичок ![]() Группа: Пользователи Сообщений: 36 Пол: Мужской Репутация: ![]() ![]() ![]() |
вопрос не в тему...
а что такое матрица??? вобщем объясните... спасибо -------------------- когда в руках молоток, все кажутся гвоздями
|
klem4 |
![]()
Сообщение
#18
|
![]() Perl. Just code it! ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 100 Пол: Мужской Реальное имя: Андрей Репутация: ![]() ![]() ![]() |
-------------------- perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
|
![]() ![]() |
![]() |
Текстовая версия | 27.07.2025 11:08 |