Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Почему FormatFloat игнорирует заданный формат вывода?  [new]
FormatFloat
Guest
День добрый уважаемые.
Ищу способ нестандартного форматирования числа, но напоролся на проблему преобразования через StrToFloat и FormatFloat.
-Очень сильно страдает точность (особенно в Single теряется разряд в целой части что недопустимо).
-Игнорирует пользовательский формат разделителя тысяч, и всегда выводит одинаковый результат

Проверяю на Delphi 10.2 Tokyo, Win10x64
Может подскажете какую альтернативу искать?
Мне нужно преобразовать число с нужным мне (пользовательским) форматированием
Если ли способы из коробки, или придется заморачиваться с велосипедом и собственноручно расталкивать разряды?
Заранее благодарствую.

Пример:
+
procedure TForm1.Button1Click(Sender: TObject);
var
  vSingle: Single;
  vDouble: Double;
  vExtended: Extended;
  S: string;
  FS: TFormatSettings;
begin
  FS := TFormatSettings.Create;
  FS.ThousandSeparator := '`';
  FS.DecimalSeparator := ',';
  S := '123456789012345,54321';
  vSingle := StrToFloat(S, FS);
  vDouble := StrToFloat(S, FS);
  vExtended := StrToFloat(S, FS);
  Memo1.Lines.Add(S + ' :String');
  Memo1.Lines.Add(vSingle.ToString + ' :Single');
  Memo1.Lines.Add(vDouble.ToString + ' :Double');
  Memo1.Lines.Add(vExtended.ToString + ' :Extended');
  Memo1.Lines.Add('--Single---');
  S := FormatFloat('#,##0.0000', vSingle, FS);
  Memo1.Lines.Add(S);
  S := FormatFloat('##,##,##,##0.0000;-##,##,##,##0.0000;0.0000', vSingle, FS);
  Memo1.Lines.Add(S);
  Memo1.Lines.Add('--Double---');
  S := FormatFloat('#,##0.0000', vDouble, FS);
  Memo1.Lines.Add(S);
  S := FormatFloat('##,##,##,##0.0000;-##,##,##,##0.0000;0.0000', vDouble, FS);
  Memo1.Lines.Add(S);
  Memo1.Lines.Add('--Extended---');
  S := FormatFloat('#,##0.0000', vExtended, FS);
  Memo1.Lines.Add(S);
  S := FormatFloat('##,##,##,##0.0000;-##,##,##,##0.0000;0.0000', vExtended, FS);
  Memo1.Lines.Add(S);
end;


на выходе получаем:
+

123456789012345,54321 :String
123456788103168 :Single
123456789012346 :Double
123456789012346 :Extended
--Single---
123`456`788`103`168,0000
123`456`788`103`168,0000
--Double---
123`456`789`012`345,5470
123`456`789`012`345,5470
--Extended---
123`456`789`012`345,5430
123`456`789`012`345,5430
2 окт 17, 14:02    [20836349]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
goldmi45
Member

Откуда:
Сообщений: 900
FormatFloat,

Почитайте про представление вещественных чисел в двоичном коде, про вещественные типы данных, тогда, возможно, часть вопросов отпадёт сама собой.
2 окт 17, 14:27    [20836421]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
Guest2013
Member

Откуда:
Сообщений: 516
goldmi45,

Я ее читал, она рассказывает про хранение чисел в памяти, и что сопроцессор для обработки все числа приводит к Extended, но это не не про преобразование из строки в число и наоборот.
И с каких пор Single - теряет точность в середине целой части при преобразовании из строки???!!!
я бы понял если бы это была дробная часть, но это уже как-то...

123456789012345,54321 :String
123456788103168 :Single
2 окт 17, 14:40    [20836455]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
s62
Member

Откуда: Жуковский
Сообщений: 707
Guest2013
...
И с каких пор Single - теряет точность в середине целой части при преобразовании из строки???!!!
я бы понял если бы это была дробная часть, но это уже как-то...

123456789012345,54321 :String
123456788103168 :Single

Если читали, то может заметили, что мантисса у Single - 23 бита. Плюс еще 1 из-за формата хранения - как написано тут http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=374 , неформально говоря, к этому добавляется слева двоичное "1." получается 24 бита. 2 в 24 степени = 16777216. Вот у вас примерно 8 знаков точности. Так у вас и получилось - 8 знаков точно, а дальше уже погрешность.
2 окт 17, 15:03    [20836528]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
чччД
Guest
Guest2013
goldmi45,

Я ее читал, она рассказывает про хранение чисел в памяти, и что сопроцессор для обработки все числа приводит к Extended, но это не не про преобразование из строки в число и наоборот.
И с каких пор Single - теряет точность в середине целой части при преобразовании из строки???!!!
я бы понял если бы это была дробная часть, но это уже как-то...

123456789012345,54321 :String
123456788103168 :Single

Нет никакой "целой" и "дробной" части. Иди, снова читай.
...
...Няшик, снова ты отжигаешь?
2 окт 17, 15:11    [20836554]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
Guest2013
Member

Откуда:
Сообщений: 516
s62,

Я Вас понимаю, но "точность" - относится к дробной части числа.
А тут на ровном месте - 9 миллионов. (на мой взгяд, тут явно просматривается ошибка в функции преобразования строки в число).
2 окт 17, 15:16    [20836565]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
s62
Member

Откуда: Жуковский
Сообщений: 707
Guest2013
s62,

Я Вас понимаю, но "точность" - относится к дробной части числа.
...
Неправильно.
Вот представьте, у вас есть байт и нужно с его помощью работать с числом 12345. Точно не получится, хотя 12345 - не дробное, а целое число. Почему? Размерчик (байта) маловат, нужно больше байтjd, чтобы точно сохранить 12345. Аналогично и в вашей ситуации с Single.
2 окт 17, 15:22    [20836587]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
s62
Member

Откуда: Жуковский
Сообщений: 707
s62,
*байтов
2 окт 17, 15:22    [20836589]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
чччД
Guest
Guest2013
...Я Вас понимаю, но "точность" - относится к дробной части числа...

Понедельник - день тяжёлый.
2 окт 17, 15:24    [20836597]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
Guest2013
Member

Откуда:
Сообщений: 516
s62,

согласен, тут целая часть вмещается в 6 байт а, не в 4 (виноват проглядел)
остается 2-я часть вопроса, произвольный формат числа (есть мысли?)
2 окт 17, 15:29    [20836619]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9914
FormatFloat
-Игнорирует пользовательский формат разделителя тысяч
Где?
FormatFloat
FS.ThousandSeparator := '`';

FormatFloat
123`456`788`103`168,0000
2 окт 17, 16:46    [20836887]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 728
чччД
...Няшик, снова ты отжигаешь?


Нет, за то не стух 😉😉😉😉
2 окт 17, 16:58    [20836910]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
Guest2013
Member

Откуда:
Сообщений: 516
_Vasilisk_,

я предполагал что FormatFloat такое умеет (но оказалось что нет):

12`34`56`78`90`12`345,54321 - '##,##,##,##,##,##,##0.0000'
12`345`678`901`2345,54321 - '###,###,###,###,###0,0000'
12345678901`2345,54321 - '############,###0,0000'
2 окт 17, 17:52    [20837091]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
Граур Станислав
Member

Откуда:
Сообщений: 871
Guest2013
я предполагал что FormatFloat такое умеет (но оказалось что нет):

12`34`56`78`90`12`345,54321 - '##,##,##,##,##,##,##0.0000'
12`345`678`901`2345,54321 - '###,###,###,###,###0,0000'
12345678901`2345,54321 - '############,###0,0000'


Тебе точно исходное значение нужно во float хранить, а не в varchar/string ?
2 окт 17, 19:10    [20837230]     Ответить | Цитировать Сообщить модератору
 Re: Почему FormatFloat игнорирует заданный формат вывода?  [new]
Guest2013
Member

Откуда:
Сообщений: 516
Граур Станислав,

Сохраняются все значения.
упрощенно:
TMyObject = class
private
  FFS: TFormatSettings;
  FValue: Extended; //число
  FText: string;  //текст
  FDisplayText: string; //отображение
  {...}
end;

- меняется число -> меняется текст и отображение
- меняется текст -> меняется число и отображение
2 окт 17, 20:19    [20837300]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить