Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 02.06.2013, 15:53
Tonyy Tonyy вне форума
Новичок
 
Регистрация: 05.04.2010
Сообщения: 85
Репутация: 10
По умолчанию почему invalid floating-point operation?

Уважаемые участники форума. прошу помочь мне разобраться в следующем моменте:
на вход программы подаю массив из 192400 числовых данных. числовой формат - single
с каждым числом необходимо проделать процедуру, чтобы поменять местами байты. в итоге в процессе выполнения программы на этапе переворачивания (свопинга) выскакивает ошибка invalid floating-point operation. если же переворачивать каждое число по отдельности по одному, а не в цикле, то все проходит нормально. пробовал переворачивать отдельно то число на котором вылетает ошибка, и предыдущее число и предшествующее - по отдельности все нормально. а если в цикле, то - беда. в чем дело?
Код:
procedure TForm1.btn2Click(Sender: TObject);
var
  ff:TextFile;
  buf:Single;
  dd:array [0..3] of  byte absolute buf;
  temp:byte;
  i:integer;
  f:TStringList;
  y:Integer;
  a:array [0..90035]of Single;
 
begin
  f:=TStringList.Create;
  f.LoadFromFile('G:\val.txt');
  //setlength(a,192400);
 // setlength(b,192400);
  for  y:=0 to 90035 do begin
    a[y]:=StrToFloat(f[y]);
  end;
  AssignFile(ff,'e:\antiswap.txt');
  Rewrite(ff);

                     //процедура которая переворачивает байты 
                   for y:=0 to 90035 do begin
                          buf:=a[y] ;
                          for i:=0 to 1 do begin
                          temp:=dd[i];
                          dd[i]:=dd[3-i];
                          dd[3-i]:=temp;
                          end;

                   Writeln(ff,buf);

  end;

 CloseFile(ff);
 f.Free;
ShowMessage('конец');

end;

во вложенном файле - входные данные. их меньше чем 192400 так как пришлось примерно половину удалить, чтобы загрузить на форум.
Вложения
Тип файла: rar val-1.rar (492.3 Кбайт, 1 просмотров)

Последний раз редактировалось Tonyy, 02.06.2013 в 18:00.
Ответить с цитированием
  #2  
Старый 02.06.2013, 16:36
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Во-первых в том файле что ты выложил всего 90036 числа, а значит этот цикл уже будет некорректный:
Код:
  for y := 0 to 192399 do
  begin
    a[y] := StrToFloat(f[y]);
  end;
Во-вторых я не пойму зачем вообще переворачивать байты в числе типа Single. Или ты думаешь что взяв корректное число типа Single и перемешав в нём байты как тебе вздумается ты получишь опять корректное число? Вот почитай что означает каждый байт в числе типа Single: Число одинарной точности
Ответить с цитированием
  #3  
Старый 02.06.2013, 16:51
Tonyy Tonyy вне форума
Новичок
 
Регистрация: 05.04.2010
Сообщения: 85
Репутация: 10
По умолчанию

да, я извиняюсь, что размер цикла не соответствует файлу задания. просто я уже выложил сначала код, а потом пришлось редактировать файл задание, чтобы его можно было выложить на форуме.
цель не в том, чтобы получить корректное число. а в том, чтобы перевернутые числа записать потом в файл, где они должны храниться перевернутыми.
Ответить с цитированием
  #4  
Старый 02.06.2013, 17:07
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Функция StrToFloat использует системный разделитель целой и дробной части. У тебя в Windows'е скорее всего установлен разделителем запятая, а в том твоём файле разделитель точка - отсюда и ошибка. Используй переменную DecimalSeparator для изменения символа разделителя целой и дробной части.
Цитата:
Сообщение от Tonyy
да, я извиняюсь, что размер цикла не соответствует файлу задания. просто я уже выложил сначала код, а потом пришлось редактировать файл задание, чтобы его можно было выложить на форуме.
Ну так можно выкладывать в другие места, например на zalil.ru
Цитата:
Сообщение от Tonyy
цель не в том, чтобы получить корректное число. а в том, чтобы перевернутые числа записать потом в файл, где они должны храниться перевернутыми.
В твоём примере я не увидел чтобы числа сохранялись в перевёрнутом виде, а вижу только как строка "Writeln(ff, buf)" выводит ужасно искажённое число (если ей конечно вообще удастся преобразовать в число тот мусор что ты ей подсовываешь).
Ответить с цитированием
  #5  
Старый 02.06.2013, 17:58
Tonyy Tonyy вне форума
Новичок
 
Регистрация: 05.04.2010
Сообщения: 85
Репутация: 10
По умолчанию

с разделителем все в порядке. часть чисел он переворачивает. работу прекращает на 553 по счету числе. отдельно и 553 и 554 по счету число переворачивается той же функцией.
Ответить с цитированием
  #6  
Старый 02.06.2013, 18:15
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Tonyy
с разделителем все в порядке. часть чисел он переворачивает. работу прекращает на 553 по счету числе. отдельно и 553 и 554 по счету число переворачивается той же функцией.
Ну так это то о чём я и писал - не любая комбинация байт в числе типа Single является корректной. Ошибка возникает на числе "-0.65840143". В памяти оно хранится в таком виде: "BF 28 8C FF", а если этот набор байт поменять местами получим "FF 8C 28 BF" - а вот это уже некорректное число типа Single. Ты всё-таки почитай в Википедии по той ссылке что я давал о типе Single и что означает каждый его байт.
Ответить с цитированием
  #7  
Старый 02.06.2013, 19:21
Tonyy Tonyy вне форума
Новичок
 
Регистрация: 05.04.2010
Сообщения: 85
Репутация: 10
По умолчанию

это печальная новость.
потому что мне надо массив этих чисел записать в не типизированный файл. при чем числа эти в файле должны храниться в перевернутом виде. а как же мне все таки тогда это сделать?
Ответить с цитированием
  #8  
Старый 02.06.2013, 19:31
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Tonyy
это печальная новость.
потому что мне надо массив этих чисел записать в не типизированный файл. при чем числа эти в файле должны храниться в перевернутом виде. а как же мне все таки тогда это сделать?
Ну так а зачем ты тогда эти "перевёрнутые" числа выводишь в текстовый файл? Проблема именно в этом - ты пытаешься некорректные числа перевести в строковое представление.
Записывай их в нетипизированный файл как бинарные данные (не интерпретируя в строку). И при чтении читай их как бинарные данные, переворачивай байты и после этого можешь смело использовать в качестве чисел типа Single.
Ответить с цитированием
  #9  
Старый 02.06.2013, 20:45
Tonyy Tonyy вне форума
Новичок
 
Регистрация: 05.04.2010
Сообщения: 85
Репутация: 10
По умолчанию

Код:
for i:=0 to 192399 do begin
Ddata1[i]:=(swapflt(data1[i])+swapflt(data2[i])+swapflt(data3[i]))/(count+1);
Ddata1[i]:=swapflt(Ddata1[i]);   //вот здесь все равно происходит ошибка
end;
vs.Write(Ddata1[0],4*192399);

это фрагмент кода. swapflt - эта функция которая переворачивает байты.
сначала данные берутся из нетипизированных файлов. с ними производятся операции. а затем результат необходимо перевернуть и записать. но происходит ошибка.

Последний раз редактировалось Tonyy, 02.06.2013 в 20:54.
Ответить с цитированием
  #10  
Старый 02.06.2013, 20:59
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Tonyy
Код:
for i:=0 to 192399 do begin
Ddata1[i]:=(swapflt(data1[i])+swapflt(data2[i])+swapflt(data3[i]))/(count+1);
Ddata1[i]:=swapflt(Ddata1[i]);   //вот здесь все равно происходит ошибка
end;
vs.Write(Ddata1[0],4*192399);

это фрагмент кода. swapflt - эта функция которая переворачивает байты.
сначала данные берутся из нетипизированных файлов. с ними производятся операции. а затем результат необходимо перевернуть и записать. но происходит ошибка.
Если функция swapflt реализована правильно, то в том месте ошибка просто не может возникнуть. Значит либо swapflt реализована неправильно, либо ошибка на самом деле в другом месте, например там где у тебя производятся какие-то математические операции.
Ответить с цитированием
  #11  
Старый 02.06.2013, 21:43
Tonyy Tonyy вне форума
Новичок
 
Регистрация: 05.04.2010
Сообщения: 85
Репутация: 10
По умолчанию

вполне возможно что swapflt кривая. но лучшей реализации пока не видел.
Код:
function swapflt(value:single):single;
var
dd:array [0..3] of  byte absolute value;
temp:byte;
i:integer;
begin

                          for i:=0 to 1 do begin
                          temp:=dd[i];
                          dd[i]:=dd[3-i];
                          dd[3-i]:=temp;
                          end;
                          result:=value;



end;
если вы подскажите мне реализацию лучше - буду вам безмерно благодарен.
Ответить с цитированием
  #12  
Старый 03.06.2013, 10:34
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

Скорее всего происходит ошибка на строке
result:=value;
Здесь происходит попытка загрузить из памяти в регистр сопроцессора некорректное число с плавающей точкой.
Вывод - не рассматривайте "перевёрнутые" данные как Single. Оставьте их как Cardinal или Array[0..3] of byte.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 11:35.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter