В некоторых проектах работа с датами, например
DateToStr() взывают ошибку типа "Invalid floating point operation", а в других все это отрабатывает
без проблем. Не подскажете, в чем может быть засада. Delphi 6, Windows 98
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
03-02-2005 10:02 | Комментарий к предыдущим ответам
>>>Set8087CW(Default8087CW);
имхо это как бы не оч правильно, т.к. Default8087CW - это переменная :)
уж лучше писать что-то определенное, напр Set8087CW($133f);
Все кто имел проблемы при конвертации даты и других флоат-поинт типов, когда с того ни с сего начинаются сообщения "Invalid Floating Point operation". Особенно когда вы вызывали какие то DLL из своей программы, например, отделили свои отчеты в DLL и их вызываете и т.п. И всё это только под Win9x/Me. Вот решение.
У меня была такая же проблема, уже годами, но не часто и не у всех пользователей (а их сотни). Но вот у одного клиента стояли принтеры HP1150 и после печати эта ошибка стабильно "вешала" наше приложение. При смене принтера это прекращалось. А клиент с его уникальным принтером за сотни км... Мы клиенту посоветовали сменить принтер. Буквально начался скандал. Пришлось уделить проблеме особое внимание. Оказалось! Если вы в Вин98/Ме вызываете какую то чужую DLL, и она в свою очередь меняет флаги (маску) проверок ошибок в арифметическом сопроцессоре, то, после, когда выполнение вернулось из DLL, в вашем приложении начинаются эти глюки. (Конечно далеко не все ДЛЛки занимаются такой фигней). Итак, наше приложение ожидает, что маску никто ни трогал и крутит все свои Дельфовые флоат-процедуры как себе знает. В моем случае менял маску очевидно драйвер принтера или какая то библиотека, относящаяся к принтеру. А если сохранять маску до вызова и восстанавливать её после, то проблема уйдет.
Get8087CW;
Set8087CW(...);
Также где-то писалось, что можно просто после вызова DLL вызвать-- asm FINIT; end;
Еще где-то говорили, что можно вот так -- Set8087CW(Default8087CW);
Мне это полностью помогло и проблема ушла. Надо отметить, что в и-нете реального решения этого практически только пару ссылок, в основном все люди только задают этот вопрос и со временем находят абсолютно "левые" решения, которые просто являются совпадением с уходом проблемы. А реальная проблема с сопроцессором. Кто бы знал!
Кто хочет изучить проблему подробнее -- вот спасшие меня ссылки:
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.