
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
Сообщ.
#1
,
|
|
|
Имеем q:extended и s:string. При попытке выполнить s:=FloatToStr(q) вылетает "invalid floating point operation". При этом q имеет значение 0.0275. Ничего не понимаю. Пробовал менять значения, скажем на q:=0.1, ошибка все равно вылетает.
|
Сообщ.
#2
,
|
|
|
![]() ![]() procedure TForm1.Button1Click(Sender: TObject); var q:extended; s:string; begin q:=0.0275; s:=FloatToStr(q); Edit1.text:=s; end; попробуй помеять точку на запятую ? Добавлено у меня правда и этот вариант работает) |
Сообщ.
#3
,
|
|
|
Цитата RusSun @ попробуй помеять точку на запятую ? Попробовал DecimalSeparator:=',' (и с точкой тоже) - не помогло. |
Сообщ.
#4
,
|
|
|
Не исключено, что ошибка случилась раньше, и в стеке сопроцессора мусор. И стоит проверить перед операцией Get8087CW
|
Сообщ.
#5
,
|
|
|
Да, видимо где-то раньше "затесалось" деление 0/0 или операция с неинициализированным вещ.числом (или неумелое использование встроенного asm'а для fpu-вычислений)
|
Сообщ.
#6
,
|
|
|
Покопался в SysUtils. Получилась примерно такая цепочка:
FloatToStr -> SetString -> FloatToText -> FloatToDecimal Вот на FloatToDecimal и запинается. С asm'ом у меня не очень, поэтому просто тупо посмотрел на содержимое регистров CPU. Цитата MBo @ И стоит проверить перед операцией Get8087CW Спасибо, почитаю хелп только. |
Сообщ.
#7
,
|
|
|
Копаться в FloatToStr бесполезно, т.к. она работает нормально.
Но специфика fpu-операций x86 такова, что исключения генерятся не на самой инструкции, вызвавшей исключение, а на следующей за ней команде fpu. Поэтому во всех встроенных дельфийских функциях для работы с вещ.числами всегда вставляется пустая fpu-команда fwait, чтобы ошибка генерилась внутри самой функции, а не где-то после ее вызова. Поэтому возможные invalid operation, связанные с неверными аргументами Sqrt, Ln и т.п. должны возникать на самом вызове этих функций. Но когда ты, например, просто делишь два числа x/y, то может возникнуть ошибка деления 0/0, которая проявится не сразу, а на какой-то другой последующей операции с fpu (в твоем случае на вызове FloatToStr, хотя дело вовсе не вней). Подобный случай тут недавно обсуждался |
Сообщ.
#8
,
|
|
|
Цитата leo @ Копаться в FloatToStr бесполезно, Да, так и получилось. После прочтения одной статьи вставил Set8087CW(Get8087CW or $0100). На несколько проходов хватало. После чего опять появлялась ошибка. Цитата MBo @ Не исключено, что ошибка случилась раньше, и в стеке сопроцессора мусор. Точно. В куске кода, выдранном из старой программы, обнаружилась пара инструкций IF, использующих две объявленных, но не инициализированных переменных. Всем спасибо! |
Сообщ.
#9
,
|
|
|
Я обычно FormatFloat использую для преобразования числа с плавающей точкой в строку. Заодно сразу и кол-во знаков после запятой указать можно.
Типа такого: ![]() ![]() s:=FormatFloat('0.00', q); |
Сообщ.
#10
,
|
|
|
Обычно такие вещи случаются при использовании библиотек с MMX-ом. Например Graphics32. В таких библиотеках обычно пишут, как и после чего переключаться снова на FP.
|
Сообщ.
#11
,
|
|
|
Dimonka
это об? ![]() ![]() asm emms end; так обычно сама библиотека и следит |
Сообщ.
#12
,
|
|
|
Цитата Lumen @ Я обычно FormatFloat использую для преобразования числа с плавающей точкой в строку. Хм... А на что можно использовать необычно? Это не сарказм, вопрос в целях повышения повышаемости. Цитата Lumen @ ![]() ![]() s:=FormatFloat('0.00', q); Кажись наоборот, формат указывается после переменной. |
Сообщ.
#13
,
|
|
|