Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.02.06;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.043 c
14-16662
Кот Бегемот
2004-01-17 13:08
2004.02.06
Люди ! ! ! Давайте жить дружно


1-16467
HolyMan
2004-01-27 22:37
2004.02.06
Как сделать цветной грид через строчку?


1-16331
oleg_SYS
2004-01-24 21:27
2004.02.06
Где находятся в реестре пункты контекстных меню?


6-16550
Haxx
2003-12-03 15:51
2004.02.06
Какая библиотека нужна для коннект с MySQL


14-16615
InBass Project
2004-01-08 08:29
2004.02.06
Вот такого я от себя не ожидал...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский