|
|
|
Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как «свернуть» программу в трей.
3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
… (продолжение следует) …
Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.
Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка — 60 дней. Последующие попытки бан.
Мат в разделе — бан на три месяца…
Ошибка при выполнении FloatToStr
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Junior Рейтинг (т): нет |
Имеем q:extended и s:string. При попытке выполнить s:=FloatToStr(q) вылетает «invalid floating point operation». При этом q имеет значение 0.0275. Ничего не понимаю. Пробовал менять значения, скажем на q:=0.1, ошибка все равно вылетает. |
RusSun |
|
Full Member Рейтинг (т): 7 |
procedure TForm1.Button1Click(Sender: TObject); var q:extended; s:string; begin q:=0.0275; s:=FloatToStr(q); Edit1.text:=s; end; попробуй помеять точку на запятую ? Добавлено 07.09.12, 02:55 |
Sandy |
|
Junior Рейтинг (т): нет |
Цитата RusSun @ 07.09.12, 02:54 попробуй помеять точку на запятую ? Попробовал DecimalSeparator:=’,’ (и с точкой тоже) — не помогло. |
MBo |
|
Не исключено, что ошибка случилась раньше, и в стеке сопроцессора мусор. И стоит проверить перед операцией Get8087CW |
leo |
|
Да, видимо где-то раньше «затесалось» деление 0/0 или операция с неинициализированным вещ.числом (или неумелое использование встроенного asm’а для fpu-вычислений) |
Sandy |
|
Junior Рейтинг (т): нет |
Покопался в SysUtils. Получилась примерно такая цепочка: Цитата MBo @ 07.09.12, 04:44 И стоит проверить перед операцией Get8087CW Спасибо, почитаю хелп только. |
leo |
|
Копаться в FloatToStr бесполезно, т.к. она работает нормально. Сообщение отредактировано: leo — 07.09.12, 08:02 |
Sandy |
|
Junior Рейтинг (т): нет |
Цитата leo @ 07.09.12, 08:00 Копаться в FloatToStr бесполезно, Да, так и получилось. После прочтения одной статьи вставил Set8087CW(Get8087CW or $0100). На несколько проходов хватало. После чего опять появлялась ошибка. Цитата MBo @ 07.09.12, 04:44 Не исключено, что ошибка случилась раньше, и в стеке сопроцессора мусор. Точно. В куске кода, выдранном из старой программы, обнаружилась пара инструкций IF, использующих две объявленных, но не инициализированных переменных. Всем спасибо! |
Lumen |
|
Я обычно FormatFloat использую для преобразования числа с плавающей точкой в строку. Заодно сразу и кол-во знаков после запятой указать можно.
s:=FormatFloat(‘0.00’, q); |
Dimonka |
|
Обычно такие вещи случаются при использовании библиотек с MMX-ом. Например Graphics32. В таких библиотеках обычно пишут, как и после чего переключаться снова на FP. |
antonn |
|
Dimonka
asm emms end; так обычно сама библиотека и следит |
Sandy |
|
Junior Рейтинг (т): нет |
Цитата Lumen @ 07.09.12, 10:52 Я обычно FormatFloat использую для преобразования числа с плавающей точкой в строку. Хм… А на что можно использовать необычно? Это не сарказм, вопрос в целях повышения повышаемости. Цитата Lumen @ 07.09.12, 10:52
s:=FormatFloat(‘0.00’, q); Кажись наоборот, формат указывается после переменной. |
Filka |
|
Senior Member Рейтинг (т): 144 |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Delphi: Общие вопросы
- Следующая тема
[ Script execution time: 0,0835 ] [ 16 queries used ] [ Generated: 4.06.23, 01:50 GMT ]
zk-protmbobi 0 / 0 / 0 Регистрация: 17.12.2015 Сообщений: 10 |
||||
1 |
||||
20.02.2017, 19:00. Показов 747. Ответов 1 Метки нет (Все метки)
Delphi7. Не могу понять как правильнее написать, он складывает edit,ы ну и считает по формуле, посмотрите может типы не те, я ввожу в edit он выводит дробь в листбокс. Что не так: не считает сумму, просто думает как строка. Складывает строки.
0 |
138 / 136 / 100 Регистрация: 10.03.2015 Сообщений: 553 |
|
20.02.2017, 19:10 |
2 |
StrToFloat(azd1+bpw1) StrToFloat(azd1)+StrToFloat(bpw1)
StrToFloat(azd2+bpw2) StrToFloat(azd2)+StrToFloat(bpw2)
1 |
Модератор: Модераторы
В общем, решил проблему «в лоб». Написал функцию, которая анализирует получившуюся строку на предмет наличия предпоследних 4 девяток или нулей:
- Код: Выделить всё
function TriaFloatToStr(f:extended):string;
var s:string;
i,j,n,LenS:integer;
ch:char;
begin
s:=FloatToStr(f);
Result:=s;
LenS:=Length(s);
//Если длина числа меньше максимального числа знаков - значит нет ошибки округления
If LenS<18 Then Exit;
n:=pos(DecimalSeparator,s);
If LenS-n>8 Then begin
ch:=s[LenS-1];
//Найдем первый знак, отличный от предпоследнего
For i:=LenS-1 downto 1 do begin
If (s[i]<>ch)and(i<>n) Then begin
//Если девяток или нулей меньше 4, то считаем, что округлять не надо
If Lens-i<5 Then Exit;If ch='9'Then begin
Case s[i] of
'0':s[i]:='1';
'1':s[i]:='2';
'2':s[i]:='3';
'3':s[i]:='4';
'4':s[i]:='5';
'5':s[i]:='6';
'6':s[i]:='7';
'7':s[i]:='8';
'8':s[i]:='9';
end;
If i>n Then begin//До десятичных - обрежем по текущую позицию
SetLength(s,i);
end
Else begin//Иначе - обрежем по целые и до точки заполним нулями
SetLength(s,n-1);
For j:=i+1 to n-1 do s[j]:='0';
end;
end
else begin//Обрежем по позицию/по целые
If i>n Then SetLength(s,i)
Else SetLength(s,n-1);
end;
Result:=s;
Exit;
end;
end;
end;
end;
По первым тестам — пока работает…
Да, функция будет работать только для вещественных double.
- tria
- постоялец
- Сообщения: 401
- Зарегистрирован: 03.04.2006 11:24:10
-
- Профиль
- Сайт
Re: Проблемы с FloatToStr()
debi12345 » 23.08.2006 20:37:33
tria писал(а):В Делфи:
FloatToStr(-58.399999999999999)=»-58.4″
В Лазаре:
FloatToStr(-58.399999999999999)=»-58.399999999999999″
Собственно вопрос в следующем.
Ка сделать, чтобы в Лазаре работало так как в Делфи?
Старый FPC-баг ( или фича ? ), связанный с промежуточным расширением числа в extended-тип. Это тип намного длиннее «float», поэтому ни о каком округлении не может быть и речи ( скажите спасибо, что еще девяток не добавляет — мог бы, да разрядов не хватает ).
Зато есть другой побочный, обратный, эффект — генерация длинной последовательности из некоторых чисел вроде «99.1».
AFAIK, единственная возможность побороть этим траблы — наша любимая «Format». Никак не въеду, чем она Вам в данном случае не угодила.
Или вышеописанным способом.
-
debi12345 - долгожитель
- Сообщения: 5749
- Зарегистрирован: 10.05.2006 23:41:15
- Откуда: Ташкент (Узбекистан)
STAKANOV » 24.08.2006 14:54:41
tria писал(а):>STAKANOV
Сори, чего-то протормозил проверить. Код:
FloatToStr(double(-58.399999999999999))
приводит к тому же результату
Попробуй на всех типах: Real, Single , Double , Extended, Comp , Currency.
Суть идеи основана на моем предположении. что результат работы функции зависит от типа ее аргумента. А вот тип аргумента fpc и delphi возможно определяют по разному.
Прим.: а вообще за борландом водятся грешки с округлением и наооборт.
-
STAKANOV - энтузиаст
- Сообщения: 1069
- Зарегистрирован: 14.05.2006 21:26:24
- Откуда: Зеленоград
-
- Профиль
- Сайт
- ICQ
Mirage » 24.08.2006 15:35:56
Странно, у меня
FloatToStr(-58.399999999999999)=»-58.399999999999999″
Delphi 7
Что я делаю не так? Если вместо числа подставить переменную типа Single с таким значением, то будет тоже самое.
А вот так все нормально:
Result := FloatToStrF(Value, ffGeneral, 7, 0);
Может и в FPC прокатит?
В документации на FloatToStrF так и сказано что надо именно FloatToStrF использовать для получения минимальной длины строки.
- Mirage
- энтузиаст
- Сообщения: 881
- Зарегистрирован: 06.05.2005 20:29:07
- Откуда: Russia
-
- Профиль
- Сайт
- ICQ
tria » 26.08.2006 19:08:24
Mirage писал(а):Странно, у меня
FloatToStr(-58.399999999999999)=»-58.399999999999999″
Delphi 7
Что я делаю не так? Если вместо числа подставить переменную типа Single с таким значением, то будет тоже самое.
Не знаю. Вы что-то не так делаете, или может результат зависит от каких-то опций.
С Single результат таким не может быть в принципе, так как Single не имеет столько значащих цифр. И если проверите (что я и сделал), то результат будет другой — -58,4000015258789.
Mirage писал(а):А вот так все нормально:
Result := FloatToStrF(Value, ffGeneral, 7, 0);
Может и в FPC прокатит?
В документации на FloatToStrF так и сказано что надо именно FloatToStrF использовать для получения минимальной длины строки.
Повторюсь где-то в 3 или 4 раз.
Я НЕ ЗНАЮ, СКОЛЬКО ЗНАКОВ ПОСЛЕ ЗАПЯТОЙ ДОЛЖНО БЫТЬ У ЧИСЛА.
- tria
- постоялец
- Сообщения: 401
- Зарегистрирован: 03.04.2006 11:24:10
-
- Профиль
- Сайт
debi12345 » 26.08.2006 19:50:08
Повторюсь где-то в 3 или 4 раз.
Я НЕ ЗНАЮ, СКОЛЬКО ЗНАКОВ ПОСЛЕ ЗАПЯТОЙ ДОЛЖНО БЫТЬ У ЧИСЛА.
Тем не менее Вы согласны ( и хотите ? ) на округление, то есть сознательно отказываетесь от абсолютной точности — вплоть до 1-го знака после запятой.
Совсем запутали, чесслово. Уж определитесь.
-
debi12345 - долгожитель
- Сообщения: 5749
- Зарегистрирован: 10.05.2006 23:41:15
- Откуда: Ташкент (Узбекистан)
tria » 26.08.2006 20:03:20
STAKANOV писал(а):
Попробуй на всех типах: Real, Single , Double , Extended, Comp , Currency.Суть идеи основана на моем предположении. что результат работы функции зависит от типа ее аргумента. А вот тип аргумента fpc и delphi возможно определяют по разному.
Прим.: а вообще за борландом водятся грешки с округлением и наооборт.
Суть проблемы в системе представления чисел.
Код:
var s:string;
f:single;
begin
f:=-58.4;
s:=FloatToStr(f);
end;
- Код: Выделить всё
Дает результат -58,4000015258789.
С double и extended - -58,4.
При этом код:
var s:string;
f:single;
d:double;
begin
f:=-58.4;
d:=f;
s:=FloatToStr(f);
Тоже даст результат -58,4000015258789.
Т.е. если ошибка уже произошла, то простым присваиванием она не будет исправлена.
Тут нужна какя-то функция преобразования из double вextended, которая бы делала не побайтное присвоение, а определяла, что число в следствии нехватки значащих цифр представлено неточно и необходимо его «подправить», чего, собственно, в Делфи похоже сделано (в FloatToStr).
- tria
- постоялец
- Сообщения: 401
- Зарегистрирован: 03.04.2006 11:24:10
-
- Профиль
- Сайт
tria » 26.08.2006 20:17:14
debi12345 писал(а):Тем не менее Вы согласны ( и хотите ? ) на округление, то есть сознательно отказываетесь от абсолютной точности — вплоть до 1-го знака после запятой.
Совсем запутали, чесслово. Уж определитесь.
Попробую разъяснить еще раз.
Не все вещественные числа могут быть точно представлены с помощью типа single или double. Простой пример:
- Код: Выделить всё
var s:string;
f:single;
begin
f:=-58.4;
s:=FloatToStr(f);
Дает результат -58,4000015258789.
Похожие примеры можно привести и для Double,и для Extended.
А теперь представьте. Пользователь вводи формулу, нажимает
«вычислить» и вместо ожидаемых -58,4 получает -58,4000015258789.
После этого он берет калькулятор, пересчитывает, получает -58,4 и посылает мою программу куду подальше.
Какое пользователю дело до проблем представления вещественных чисел?
- tria
- постоялец
- Сообщения: 401
- Зарегистрирован: 03.04.2006 11:24:10
-
- Профиль
- Сайт
STAKANOV » 26.08.2006 23:47:14
tria писал(а):После этого он берет калькулятор, пересчитывает, получает -58,4 и посылает мою программу куду подальше.
Какое пользователю дело до проблем представления вещественных чисел?
это не решаемая проблема тонкости двоичной арифметики 0.05 в десятичной — это 0.000011(0011) в двоичной, т.е. периодическая дробь, об этом рекомендую рассказать заказчику с калькулятором (калькулятор работает не в двоичной системе), весь мир с этим смирился и он пусть тоже
в дельфи видно все таки что-то сдели специально (и наверняка это вылезет боком в другом месте), чтоб улучшить ситуацию, поэтому можно смело слать баг-репорт команде fpc
хотя может это тот типичный для компьютеров случай когда от перестановки мест слагаемых сумма меняется но это опять же к fpc-team — они обещали совместимость с дельфи
Последний раз редактировалось STAKANOV 26.08.2006 23:53:45, всего редактировалось 1 раз.
-
STAKANOV - энтузиаст
- Сообщения: 1069
- Зарегистрирован: 14.05.2006 21:26:24
- Откуда: Зеленоград
-
- Профиль
- Сайт
- ICQ
debi12345 » 26.08.2006 23:53:28
Почему «extended» не протестировали ( как Вам уже советовали ), прежде чем продолжать дискуссию ?
Только что проверено для fpc-2.0.4-rc3 :
—————
var s:string;
f:extended;
begin
f:=-58.4;
s:=FloatToStr(f);
————
печатает именно «-58.4»
Думаю, для «extended» не выполняется промежуточной конверсии ( в опять же «extended» ), искажающей результат.
extended:=-58.3(9) требует как минимум 15 цифр «9» после «3» для выполнения округления в «-58.4», и это 100% правильно.
-
debi12345 - долгожитель
- Сообщения: 5749
- Зарегистрирован: 10.05.2006 23:41:15
- Откуда: Ташкент (Узбекистан)
Mirage » 27.08.2006 12:05:51
debi12345:
Я НЕ ЗНАЮ, СКОЛЬКО ЗНАКОВ ПОСЛЕ ЗАПЯТОЙ ДОЛЖНО БЫТЬ У ЧИСЛА.
Почитайте описание FloatToStrF. Там не надо знать кол-во знаков. Оно определяется само. Надо лишь знать тип аргумента. Последний параметр должен быть 7/15/18 соот-но для single, double и extended, а кол-во знаков после запятой в строке определится само. Правда это в Дельфи. Незнаю как оно работает в FPC.
- Mirage
- энтузиаст
- Сообщения: 881
- Зарегистрирован: 06.05.2005 20:29:07
- Откуда: Russia
-
- Профиль
- Сайт
- ICQ
tria » 28.08.2006 11:32:29
debi12345 писал(а):Почему «extended» не протестировали ( как Вам уже советовали ), прежде чем продолжать дискуссию ?
Я проверял. Да, с -58.4 extended не дает ошибки.
И Double не дает. Но в моем случае это не помогает.
Мне надо решить задачу в принципе, а не для конкретного случая.
В моем конкретном случае один из аргументов выражения «приходит» из SQL-запроса к FIrebird и уже содержит ошибку округления (столбец в Group by).
Дальнейшее присвоение значения результата переменной типа extended эту ошибку не исправляет.
- tria
- постоялец
- Сообщения: 401
- Зарегистрирован: 03.04.2006 11:24:10
-
- Профиль
- Сайт
tria » 28.08.2006 11:38:53
Mirage писал(а):debi12345:
Почитайте описание FloatToStrF. Там не надо знать кол-во знаков. Оно определяется само. Надо лишь знать тип аргумента. Последний параметр должен быть 7/15/18 соот-но для single, double и extended, а кол-во знаков после запятой в строке определится само. Правда это в Дельфи. Незнаю как оно работает в FPC.
Не знал, спасибо.
Проверил на Лазарусе:
- Код: Выделить всё
var f:single;
s:string;
begin
f:=-58.4;
s:=FloatToStrF(f,FFfixed,7,7);
Результат: -58.4000015
В Делфи: -58.4
А жаль…
- tria
- постоялец
- Сообщения: 401
- Зарегистрирован: 03.04.2006 11:24:10
-
- Профиль
- Сайт
alexs » 28.08.2006 15:36:38
В моем конкретном случае один из аргументов выражения «приходит» из SQL-запроса к FIrebird и уже содержит ошибку округления (столбец в Group by).
А что за запрос ты используеш? какой тип данных
надо лечить причину — а не бороться со следствиями
увеличь точность в базе данных.
-
alexs - долгожитель
- Сообщения: 4011
- Зарегистрирован: 15.05.2005 23:17:07
- Откуда: г.Ставрополь
-
- Профиль
- Сайт
- ICQ
tria » 28.08.2006 15:45:44
alexs писал(а):В моем конкретном случае один из аргументов выражения «приходит» из SQL-запроса к FIrebird и уже содержит ошибку округления (столбец в Group by).
А что за запрос ты используеш? какой тип данных
надо лечить причину — а не бороться со следствиями
увеличь точность в базе данных.
GROUP BY по столбцу Decimal(12,2).
Получаю данные как q.fields[x].AsVariant;
Насколько я понял, FIBL в этом случае берет данные как AsFloat.
- tria
- постоялец
- Сообщения: 401
- Зарегистрирован: 03.04.2006 11:24:10
-
- Профиль
- Сайт
Вернуться в Lazarus
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4
once again conversion problem in Delphi. I’ve been through some other topics, that refer to similar problem, but nothing seems to work..
What I want to do is to simple convert computetd solution ( in Extended format ) to String and then display it in TMemo.
I tried these :
FloatToStrF( value, ffExponent, 15, 2 );
and I also tried to set these :
procedure TfrmMain.FormCreate(Sender: TObject);
begin
DecimalSeparator := '.';
Application.UpdateFormatSettings := false;
end;
and then use the simpliest one :
FloatToStr
but I still can’t get it working. I’ve no idea why it works here :
http://delphi.about.com/library/rtl/blrtlFloatToStrF.htm
and doesn’t in my program. I know that there is also 2nd version of FloatToStr with second parameter, but I haven’t used it before and I am rather not a Delphi expert, so could someone give me an example code of the 2nd version of FloatToStr ?
best regards
297
03 октября 2009 года
koodeer
1.2K / / 02.05.2009
Во-первых, нет никакого желания разбирать крохотные буковки-циферки на скриншоте… Но всё же я это сделал.
Во-вторых,
в универе пробовал все получалось
Не верю! (с)
Как оно могло получаться? С такими-то ошибками в коде!
Компилятор ясно даёт понять:
Цитата:
Too many actual parameters.
Я не спец в Делфях, но с ходу нарыл описание функции FloatToStr
Код:
1 function FloatToStr ( Value : Extended ) : string;
2 function FloatToStr ( Value : Extended; const FormatSettings : TFormatSettings ) : string;
Данная функция принимает один или два параметра. А в коде их сколько?..