Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does FloatToStr ignore ThousandSeparator?

Tags:

delphi

I am trying to convert a Double and/or Currency to a string for usage in an SQL call. This means I am always interested in ThousandSeparator being nothing and DecimalSeparator being '.'.

Of course, since my machine's locale is configured to Danish, Windows will return '.' for ThousandSeparator and ',' for DecimalSeparator. As such I need to compensate for the very likely case of the locale being wrong.

Moreover, my code needs to work in both D2007 (for legacy reasons) and XE3. As such the code looked like this:

{$IF CompilerVersion>=19}
fms := TFormatSettings.Create(LOCALE_SYSTEM_DEFAULT);
{$ELSE}
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, fms);
{$IFEND}
fms.ThousandSeparator := '?';
fms.DecimalSeparator := '.';
Result := FloatToStr(Val, fms);
Result := StringReplace(Result, '?', '', [rfReplaceAll]);

Of course, one could argue that since we presume FloatToStr to only ever make use of TFormatSettings' ThousandSeparator and DecimalSeparator creating it with any locale would be pointless as we are overwriting them anyway.

Still, I thought this was a lot of code for a very simple operation. I was also not a fan of the ThousandSeparator being '?' and then being removed by StringReplace(). But since ThousandSeparator is a char, it cannot actually be blank.

I ran some tests on FloatToStr and FloatToStrF to be sure, at which point I noticed that TFormatSettings.ThousandSeparator was completely ignored:

fms := TFormatSettings.Create;
fms.ThousandSeparator := 'W';
fms.DecimalSeparator := '.';
Writeln(FloatToStr(1234567.8901, fms));
Writeln(FloatToStrF(1234567.8901, ffFixed, 18, 4, fms));

I would expect each result to be '1W234W567.8901', but instead it was just '1234567.8901'. So I wonder if this is expected behaviour or an oddity.

Because even if I cannot avoid TFormatSettings, if I can at least ignore the ThousandSeparator, I suppose I would have saved two lines of code (not that it matters that much, I suppose), but would it be safe to do so? Can I always expect FloatToStr to ignore the ThousandSeparator?

like image 479
Svip Avatar asked Jul 03 '14 10:07

Svip


1 Answers

Only certain of the floating point formats take note of the thousand separators. FloatToStr is a function that does not because it uses the ffGeneral value of the TFloatFormat enumerated type.

Can I always expect FloatToStr to ignore the ThousandSeparator?

Yes, the thousand separator is always ignored by FloatToStr.


Should you wish to have the thousand separator appear, use ffNumber. For instance the %n number format string.

Writeln(Format('%n', [1234567.8901]));
like image 124
David Heffernan Avatar answered Sep 22 '22 20:09

David Heffernan