Why does FloatToStr ignore ThousandSeparator?
delphi
Solution
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]));
Problem
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`?