2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Ошибка "invalid floating point operation" [Delphi]
Сообщение13.06.2011, 12:07 
Уважаемые форумчане, большая просьба помочь.
Пишу программу на Delphi для диплома. Но во время исполнения кода вылетает ошибка, все никак не могу понять ее природу.
Ниже приведен кусок процедуры в которой вылетает ошибка:

procedure TStakeholder.calculation_U();
var
i,j,y: integer;
TC, TC1, alpha, X1, X2, X3, U1: real;
begin
U1:=0;
for i:=0 to length(X)-1 do begin
X1:=X[i].P.value; // Это переменные класса TStakeholder, когда делал пошаговую прогонку они имели
X2:=X[i].Cost; // значения. Тип у них real.
X3:=X[i].Count; //
U1:=U1+(X1-X2)*X3; //На этой строчке вылетает ошибка "invalid floating point operation"
end;
end;

Вроде все переменные одного типа. Никаких делений нет. Даже не могу представить, что это.
При этом один раз этот цикл проходит нормально, но стоит программе выйти на него повторно и сделать те же самые действия, то выскакивает ошибка. До этого была подобная ошибка в другом месте. Складывается ощущение, что после второго обнуления переменная просто не хочет работать, в любой операции выдает ошибку.
Есть подозрение, что во время исполнения кода происходит какое-то преобразование типа переменной, но я с таким раньше не сталкивался.
Прошу помочь разобраться.

-- Пн июн 13, 2011 20:14:51 --

Проверил свое предположение, немного поправил код:

U1:=0;
for i:=0 to length(X)-1 do begin
X1:=X[i].P.value;
X2:=X[i].Cost;
X3:=X[i].Count;
if U1=0 then U1:=0; // теперь ошибка здесь появляется
U1:=U1+(X1-X2)*X3;
end;

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение13.06.2011, 20:31 
Честно говоря, не могу сообразить... Ну покажите хотя-бы объявление массива X (индексирование точно с нуля ведется?); если возможно, то и объявление TStakeholder. А вообще, смотрите в режиме отладки, какие значения приобретаются вашими переменными (в delphi ide достаточно при пошаговом исполнении курсор к переменной подводить и смотреть; но если хотите, надобавляйте отладочную печать).

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение13.06.2011, 21:33 
Например, если X1=+Inf и X3=0, то получится умножение $0\cdot\infty$, что тоже может вызвать ошибку.
Вставьте в цикл распечатку X1, X2, X3 и U1, и посмотрите, что было перед ошибкой.

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение14.06.2011, 11:22 
В том и дело, что перед ошибкой в Watch U1=0.
Все делал пошагово и отсматривал.
У меня возникает также предположение, что я как-то не так инициализирую объект класса TStakeholder.
Есть такой класс:

TGroup_Stakeholders = class(TObject) // класс группы стейкхолдеров, описывает управление группой

private

public
Group_stat: array of TStakeholder;
procedure create_save(count: integer);
end;

Собственно каждый новый элемент массив Group_stat создается так:

procedure TGroup_Stakeholders.create_save(count: integer);
var
i: integer;
S: array of TStakeholder;
begin
setlength(S, length(Group_stat));
for i:=0 to length(Group_stat)-1 do begin
S[i]:=Group_stat[i].Create;
end;
Group_stat:=nil;

setlength(Group_stat, length(S)+count);

for i:=0 to length(s)-1 do begin
Group_stat[i]:=S[i].Create;

end;
for i:=length(s) to (length(S)+count-1) do
Group_stat[i]:=TStakeholder.Create;

end;
end;

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

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение14.06.2011, 17:25 
2Shtirlic
Строки вида S[i]:=Group_stat[i].Create мне непонятны. Ладно бы там было S[i]:=TStakeholder.Create;... К тому же в начале у вас написано setlength(S, length(Group_stat)), а чему спрашивается равно length(Group_stat) изначально-то? Ужас.

В общем, разберитесь с конструированием всех этих объектов, это должно помочь. Т.е., возможное объяснение вашей ошибке может заключаться в обращении к несконструированному объекту, точнее говоря, к неинициализированным полям, в которых в определенный момент может лежать мусор, интерпретируемый, ну например, как тот же +inf, скажем...

-- Вт июн 14, 2011 20:29:34 --

Другими словами, вся ваша функция create_save должна быть переписана и заменена на что-то простое, вроде этого:
Код:
SetLength(Group_stat, count-1);
for i:=0 to count-1 do
    Group_stat[i]:=TStakeholder.Create;


-- Вт июн 14, 2011 20:30:41 --

Shtirlic писал(а):
В том и дело, что перед ошибкой в Watch U1=0.

Дык, это-то понятно. Надо смотреть на X1, X2, X3.

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение15.06.2011, 12:29 
Circiter
Код:
SetLength(Group_stat, count-1);
for i:=0 to count-1 do
    Group_stat[i]:=TStakeholder.Create;

В таком виде тоже выдавалась ошибка.
Ошибка выдавалась на этой строчке:
Код:
if U1=0 then U1:=0;

X1, X2, X3 - тоже имеют нормальные значения.

На самом деле в сути проблемы так и не разобрался, но стоило сменить компилятор с Delphi 7 на Delphi 2010 так все заработало.
Может я что не так сделал, а может и просто глюк компилятора был.

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение17.06.2011, 19:36 
Shtirlic в сообщении #458272 писал(а):
На самом деле в сути проблемы так и не разобрался, но стоило сменить компилятор с Delphi 7 на Delphi 2010 так все заработало.
Может я что не так сделал, а может и просто глюк компилятора был.


На глюк компилятора не надо надеяться. А вот замечание Circiter
Circiter в сообщении #457674 писал(а):
Ну покажите хотя-бы объявление массива X (индексирование точно с нуля ведется?); если возможно, то и объявление TStakeholder.


следовало бы обработать.
Shtirlic в сообщении #457408 писал(а):
X1:=X[i].P.value; // Это переменные класса TStakeholder, когда делал пошаговую прогонку они имели
X2:=X[i].Cost; // значения. Тип у них real.
X3:=X[i].Count; //

Пусть .Cost и .Count real, а .P.value нужно знать тип P. Типы конечно транслятор проверил, а инициализация :?:
Тип массива X из комментариев не восстановить. С уважением,

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение17.06.2011, 21:34 
Присваивание .0 вместо 0 не поможет? Вроде бывало у меня такое по неизвестной причине (ведь, и правда, тип должен нормально приводиться).

-- Сб июн 18, 2011 00:41:02 --

И вроде бы как раз на D7 было.

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение18.06.2011, 11:02 
hurtsy
Надо не надо, но программа дописана и работает!=)
Сейчас скомпилировал в Delphi 7, там тоже заработало!=)
P - это переменная обычной записи(record).
X - обычный динамический вектор, выход за пределы массива я не замечал.

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение18.06.2011, 12:05 
Я, кстати, нашел одно место, где потенциально могла происходить ошибка:

Код:
while (X[y].Count=X[y].Max.value) and (y<=length(X)-1) do // здесь
              inc(y);
if (y<=length(X)-1) then begin...


Но в том месте, где ошибка происходила судя по всему все было хорошо.
Вот у меня и возникает вопрос: может ошибка возникнуть в одном месте, а подать о себе голос несколько шагов спустя?
Я еще раз повторюсь, что я делал пошаговую проверку и конкретно перед местом ошибки проверял все параметры X, y и т.п. После жал F7 и происходила ошибка.

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение18.06.2011, 21:18 
Shtirlic в сообщении #459400 писал(а):
Вот у меня и возникает вопрос: может ошибка возникнуть в одном месте, а подать о себе голос несколько шагов спустя?
Я еще раз повторюсь, что я делал пошаговую проверку и конкретно перед местом ошибки проверял все параметры X, y и т.п. После жал F7 и происходила ошибка.


Именно так себя ведут ошибки связанные с "утечкой памяти" и это самые трудные для поиска ошибки.
Поэтому и говорится о "радости программиста" при нахождении своей ошибки. Пишите программы и будут у Вас "радости". :wink: С уважением,

 
 
 
 Re: Ошибка "invalid floating point operation"
Сообщение18.06.2011, 21:50 
hurtsy
Мда... Но, к счастью, Delphi 2010 пока выдает ошибку именно там, где она произошла (по край не мере, если ее подсвечивает).

Спасибо всем за помощь.

 
 
 [ Сообщений: 12 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group