![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
xkor |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 8.1.2007 Где: Питер Репутация: 1 Всего: 4 |
Доброго времени суток.
Столкнулся с абсолютно непонятной мне проблемой при работе с вещественными числами. Моя программа принимает координаты различных объектов в виде 3х чисел типа Single (в программе уже хранятся в типе Double), далее необходимо их округлить с заданной точностью (6 знаков после запятой) и записать в файл, но вот при округлении изредка происходит какая то не объяснимая вещь, при абсолютно нормальных числах (например 583.23472547134) функция RoundTo из модуля Math вываливается с сообщением "Invalid floating point operation". Судя по дебагеру вываливается при вызове внутри неё Round на одной из ассемблерных команд: FISTP qword ptr [ESP] FWAIT И самое непонятное что если при дебуге поймать вылет, списать значение округляемой переменной и потом в тестовой программе вызвать функцию округления с теми же параметрами то никаких ошибок не возникает. В общем может кто знает что происходит и как сделать чтобы работало без сбоев? |
|||
|
||||
RomanEEP |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 424 Регистрация: 18.5.2006 Где: Коломна Репутация: 5 Всего: 8 |
Используешь OpenGL или какие либо другие библиотеки, которые вызывают функцию Set8087CW()? Какая версия Delphi?
|
|||
|
||||
xkor |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 8.1.2007 Где: Питер Репутация: 1 Всего: 4 |
RomanEEP, нет, приложение довольно простенькое, одно окошко, кнопка и ещё пара стандартны контролов, принимает данные по WM_CopyData от другого приложения, отсеивает нужные и сохраняет в файл в виде JSON строки, с вещественными числами работает только в одном месте где просто их округляет. Дельфя 2007я.
ЗЫ программа шифруется с помощью VMProtect, но не думаю что он использует Set8087CW. Я тут подумал может вызов SetPrecisionMode(pmDouble) перед округлением поможет, вдруг и правда Set8087CW где то вызывается, правда помогло ли узнаю не скоро, редко эта ошибка вылазит. |
|||
|
||||
Bitter |
|
|||
![]() Опытный лентяй ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1209 Регистрация: 15.8.2004 Где: Харьков, Ukraine Репутация: нет Всего: 27 |
Возхможно дело не в функции округления, бывает такое, что ошибка вылазит даже на более простых операциях типа X := 0; Возможно, что где-то у тебя происходит либо выход за пределы массива или RangeCheck Error, или еще что-то связанное с "неправильным" доступом к памяти. Тогда это проявляется в виде таких вот invalid floating в других частях программы. Почему так происходит не могу точно объяснить, но у меня такое иногда бывает.
|
|||
|
||||
RomanEEP |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 424 Регистрация: 18.5.2006 Где: Коломна Репутация: 5 Всего: 8 |
В общем причина проблемы видимо следующая: в сопроцессоре есть набор флагов управляющие вызовом/не вызовом исключительных ситуации. Их состояние можно посмотреть в отладчике View->Debug Windows->FPU
Знаит они следующее: 0 -> IM Invalid Operation 1 -> DM Denormalized Operand 2 -> ZM Zero Divide 3 -> OM Overflow 4 -> UM Underflow 5 -> PM Precision Если флаг взведен, значит исключение маскируется, т.е. не вызывается. Можно поделить на ноль и никакой ошибки не выскочит. Чудеса появляются тогда, когда какая-нибудь процедура пытается поменять состояние этих флагов. Она(процедура) может поменять состояние этих флагов командой fldcw, и программа будет нормально работать. НО: вызов любой команды сопроцессора, после того как исключения были размаскированы приведет к появлению ошибки, кот произошла последней на тот момент, когда исключения были замаскированы! Я думаю надо просто посмотреть при старте программы не замаскированы ли в программе исключения. И поискать места их возможной установки. Особенно распостраненны такие места в разных функциях округления. Такой косяк был в системных функциях в Delphi 5 и был поправлен в семерке. Может в 2007 его внесли снова))) |
|||
|
||||
RomanEEP |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 424 Регистрация: 18.5.2006 Где: Коломна Репутация: 5 Всего: 8 |
||||
|
||||
Staruha |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1292 Регистрация: 1.2.2004 Где: Казань Репутация: 1 Всего: 27 |
У меня такая ошибка выскакивала.Проблема точка или запятая
-------------------- Возмездие настигнет |
|||
|
||||
profesiachuvak |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 283 Регистрация: 7.11.2009 Где: Беларусь, Минск Репутация: нет Всего: 4 |
Похоже нужно так:
583,23472547134 На разных машинах которых я работал, требовалась то точка, то запятая. Похоже в этом ошибка. Добавлено через 1 минуту и 47 секунд Точно!Не заметил. Это сообщение отредактировал(а) profesiachuvak - 17.1.2010, 19:44 -------------------- Закон Мерфи :если есть вероятность того, что какая-нибудь неприятность может случиться, то она обязательно произойдет. |
|||
|
||||
Staruha |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1292 Регистрация: 1.2.2004 Где: Казань Репутация: 1 Всего: 27 |
Добавь на вкладку Project
между begin и end
-------------------- Возмездие настигнет |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |