Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.06;
Скачать: CL | DM;

Вниз

EInvalidOp :0( - (ошибка при операциях с плавающей точкой)   Найти похожие ветки 

 
Zergling ©   (2004-01-28 08:43) [0]

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

Возьму отдельную часть:

...
RDCount := 0;
RecSize_1 := SizeOf(SmallInt) * ReadDB.ParamCount;
RecSize_2 := SizeOf(TDateTime);
...
try
FileMode := 0;
Reset(FileX, 1);
try
FSize := FileSize(FileX);
ошибка -> RecCount := Round(FSize / (RecSize_1 + RecSize_2));
except
MessageDlg(SysErrorMessage(GetLastError), mtError, [mbOk], 0);
end;
...

Значение переменных вовремя отладки:
FSize := 172368;
RecSize_1 := 1000;
RecSize_2 := 8;

При этом выводится следующее сообщение: ... EInvalidOp ... "Invalid floating point operation".
Глянул хелп: что данная ошибка выводится при ошибке операции с плавающей/переполнении точкой или если процессор наткнулся на неопределенную инструкцию. Прямо незнаю, должно как вроде получиться красивое целое число.
Или может опять я торможу :( ?

P.S. Замечу что перед этой ошибкой процедура нармально обрабатывает 327 параметров т.е. нормально вызывается 327 раз подряд в цикле, а вот на 328 такой странный глюк. Данной процедуре надо считать 500 параметров.

// Считывание данных из БД. Данные записываются в массив ValParamDB: TValParamDB
procedure ReadFileDB(const ListFile: PChar; MinDateTime, MaxDateTime: Double; NumParam: Integer;
OpisParam: TOpisParam; const ValParamDB: Pointer; ReadDB: TReadDB);
var
FileX: File;
RecX: TRecX;
ArrayData: PValParamDB; // Указатель на массив с данными
TmpFileList: TStringList; // Список файлов
I, J, // Счетчик цикла
RDCount, // Сколько данных реально занесено в динамический массив,
// а так же указывает, с какого [индекса-1] массива записывать данные
RecSize_1, RecSize_2, // Хранит размер записи
RecCount: Integer; // Количество записей в файле
TmpVal, // Для промежуточных вычислений
DifirenceScale: Double; // Разность между мин и макс шкалой
FSize: Integer;

// Добавление данных в массив по значению
procedure AddData;
begin
case ReadDB.ParamRead of
prAll:
begin
Inc(RDCount);
ArrayData^[RDCount - 1].Value := TmpVal;
ArrayData^[RDCount - 1].Date := RecX.Date;
end;
prInZoneScale:
begin
if (TmpVal >= OpisParam.ScaleLow) and (TmpVal <= OpisParam.ScaleHigh) then
begin
Inc(RDCount);
ArrayData^[RDCount - 1].Value := TmpVal;
ArrayData^[RDCount - 1].Date := RecX.Date;
end;
end;
prInZoneSettings:
begin
if (TmpVal < OpisParam.SettingLow) and (TmpVal > OpisParam.SettingHigh) then
begin
Inc(RDCount);
ArrayData^[RDCount - 1].Value := TmpVal;
ArrayData^[RDCount - 1].Date := RecX.Date;
end;
end;
end;
end;

begin
if (ListFile = NIL) or (ReadDB.ParamCount < 1) or (ValParamDB = NIL) then EXIT;
ArrayData := ValParamDB;
SetLength(RecX.Items, ReadDB.ParamCount);
RDCount := 0;
RecSize_1 := SizeOf(SmallInt) * ReadDB.ParamCount;
RecSize_2 := SizeOf(TDateTime);
if not ReadDB.AppendData then SetLength(ArrayData^, 0) else
if Length(ArrayData^) <= 0 then RDCount := 0 else RDCount := Length(ArrayData^);
// получем список файлов необходимых для работы
try
TmpFileList := TStringList.Create;
TmpFileList.Text := ListFile;
// если список пуст то завершем работу
if TmpFileList.Count < 1 then
begin
SetLength(ArrayData^, 0);
EXIT;
end;
DifirenceScale := OpisParam.ScaleHigh - OpisParam.ScaleLow;
if DifirenceScale = 0 then DifirenceScale := 1;
// перебираем весь список файлов
for I := 0 to TmpFileList.Count-1 do
begin
if FileExists(TmpFileList.Strings[I]) then
begin
AssignFile(FileX, TmpFileList.Strings[I]);
try
FileMode := 0;
Reset(FileX, 1);
try
FSize := FileSize(FileX);
RecCount := Round(FSize / (RecSize_1 + RecSize_2));
except
MessageDlg(SysErrorMessage(GetLastError), mtError, [mbOk], 0);
end;
SetLength(ArrayData^, RDCount + RecCount);
for J := 1 to RecCount do
begin
BlockRead(FileX, RecX.Items[0], RecSize_1);
BlockRead(FileX, RecX.Date, RecSize_2);
case ReadDB.Controller of
ctRemikont130: TmpVal := OpisParam.ScaleLow + RecX.Items[NumParam - 1] / 16380 * DifirenceScale;
ctAutolog: if ReadDB.Discrete then TmpVal := RecX.Items[NumParam - 1] else
TmpVal := OpisParam.ScaleLow + RecX.Items[NumParam - 1] / 255 * DifirenceScale;
end;
AddData;
end;
finally
// закрываем файл
CloseFile(FileX);
SetLength(ArrayData^, RDCount);
end; // Try
end; // if FileExists
end; // for I := 0 to TmpFileList.Count-1
finally
TmpFileList.Free;
end;
end;


 
PVOzerski ©   (2004-01-28 11:55) [1]

А зачем здесь вообще использовать операции с плавающей точкой? Тем более с Round. Длина записи - заведомо целое число, их количество в файле - тоже. Если не целое - значит, файл поврежден, и "неполная" запись все равно чтению не подлежит. RecCount := FSize div (RecSize_1 + RecSize_2) не пробовали?


 
Zergling ©   (2004-01-28 13:12) [2]

PVOzerski © (28.01.04 11:55) [1]

Точно, оно!!!. Но почему происходит такая ошибка, непросветите?
Ведь по логике как вроде все верно :). Почему у меня такая строка непроходит? A := FSize / (RecSize_1 + RecSize_2), где A: Double


 
Zergling ©   (2004-01-29 08:20) [3]

Ага, опять моя невнимательность! Нашел источник ошибки. Было у меня условие при котором запись OpisParam: TOpisParam не заполнялась данными (что неверно), врезультате чего в этой структуре был всякий мусор из памяти и значения в ней были неопределены (NIN). Врезультате выплываля ошибка и в этой строке:
TmpVal := OpisParam.ScaleLow + RecX.Items[NumParam - 1] / 255 * DifirenceScale;

Только вот почему при незаполненой записи OpisParam: TOpisParam выползала ошибка еще и на этой строке:
RecCount := Round(FSize / (RecSize_1 + RecSize_2));
для меня осталось загадкой :(
Когда исправил глюк с заполнением записи OpisParam: TOpisParam поробовал для интереса применить с Round
RecCount := Round(FSize / (RecSize_1 + RecSize_2)) (сейчас уменя как советовал PVOzerski ©);

И с Round все нормально заработало.
Почему так???
Ведь RecCount := Round(FSize / (RecSize_1 + RecSize_2)) никакого отношения к OpisParam: TOpisParam не имеет :(.
Чето этого я непонял!

Недумал что иза такого незаполнения записей могут быть такие жесткие глюки. Мда надобыть более внимательным ;-)



Страницы: 1 вся ветка

Текущий архив: 2004.02.06;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.02 c
1-16289
GS
2004-01-26 02:42
2004.02.06
Ч-з что работать с xml


6-16552
Паша Т
2003-12-02 21:42
2004.02.06
IdFTP


1-16305
SeS
2004-01-23 18:15
2004.02.06
Забор значений из файла


1-16256
denis24
2004-01-26 12:18
2004.02.06
checklistbox.drawitem


7-16750
Вованчик
2003-11-20 09:35
2004.02.06
Фискальный регистратор