7

What am I doing wrong here? I simply want to convert a formatted string to a double and using the TFormatSettings passed in as a parameter to StrToFloat. I get the following exception:

  '3,332.1' is not a valid floating point value.  

The thousand separator and decimal separator are the expected values (',' and '.') in TFormatSettings.

procedure TForm2.Button1Click(Sender: TObject);
var
  FS: TFormatSettings; 
  S: String;
  V: double;
begin
  FS:= TFormatSettings.Create; 
  codesite.Send('ThousandSeparator', FS.ThousandSeparator);  //correct ','
  codesite.Send('DecimalSeparator', FS.DecimalSeparator);    //correct '.'
  S := '3,332.1';
  try
    V := StrToFloat(S, FS);
  except on E: Exception do
    ShowMessage(e.Message);
  end;
  CodeSite.Send('S', S);
  CodeSite.Send('V', V);
end;
Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
Mike Stephenson
  • 649
  • 6
  • 14

2 Answers2

9

This behaviour is as designed. From the documentation, with my emphasis:

Use StrToFloat to convert a string, S, to a floating-point value. S must consist of an optional sign (+ or -), a string of digits with an optional decimal point, and an optional mantissa. The mantissa consists of 'E' or 'e' followed by an optional sign (+ or -) and a whole number. Leading and trailing blanks are ignored.

The DecimalSeparator global variable or its TFormatSettings equivalent defines the character that is used as a decimal point. Thousand separators and currency symbols are not allowed in the string. If S does not contain a valid value, StrToFloat raises an EConvertError exception.

So it is a mistake to pass a string containing a thousands separator to this function.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Why the FloatToStrF put the Thousand separator ? It is not a very consistent design, I think ... – aleroot Sep 14 '14 at 07:51
  • 1
    You can argue all you like about the design. I personally think the design is fine. But it's wrong to argue that it is a bug. – David Heffernan Sep 14 '14 at 07:54
  • And regarding the design, the function that matches StrToFloat is FloatToStr isn't it? – David Heffernan Sep 14 '14 at 08:01
  • Yes, it could be. But is there a matching FloatToStrF ? – aleroot Sep 14 '14 at 08:02
  • As already said, you are right about the fact that it should not be called BUG, but the feature request make sense in my opinion . – aleroot Sep 14 '14 at 08:05
  • The matching function is `FloatToStr` – David Heffernan Sep 14 '14 at 13:08
  • 2
    It seems silly to me that the StrToFloat function optionally allows a formatsettings parameter to be passed. I suppose you could argue the function would want to know which character is the decimal point but then completely disregard the thousand separator. So it's not a bug per the documentation, but it's a confusing design in my opinion. – Mike Stephenson Sep 14 '14 at 17:59
  • @Mike What about date separators? Should they be used? Or all the other fields of TFormatSettings. The design is just fine, in my view. I don't want the function checking all that other stuff. Ask yourself why FloatToStr ignores thousands seps? Perfectly consistent. – David Heffernan Sep 14 '14 at 18:22
3

What you are doing here is correct, but you stumbled in what it seems a bug(if not a bug at least a not very consistent behaviour) of the TextToFloat(it seems that it ignores ThousandSeparator) internal function of Delphi SysUtils unit(take a look at the Q92265 to follow resolution ) ...

As a workaround you can try removing the group separator, in this way :

StringReplace('3,332.1', ',', '', [rfReplaceAll])
aleroot
  • 71,077
  • 30
  • 176
  • 213
  • thanks! I was wondering if it was a bug but had a hard to believing it would exist in a simple function. My workaround is just remove the thousand separator and the conversion works as expected. – Mike Stephenson Sep 13 '14 at 22:49
  • That's exactly what I did (StringReplace) – Mike Stephenson Sep 13 '14 at 22:54
  • 5
    It's not a bug. It is by design. The documentation is quite clear. – David Heffernan Sep 14 '14 at 06:09
  • @David Heffernan If you see the Q92265 you can notice that the FloatToStrF put the the thousand separator when the opposite StrToFloat doesn't care about this ... If it is by design, it is not a very consistent design . The case is yet open and not closed by embarcadero so I think they recognize it as a BUG – aleroot Sep 14 '14 at 07:49
  • That's not what an open QC report means. And the QC report actually is a feature request. Read it closely. – David Heffernan Sep 14 '14 at 07:54
  • Ok, maybe you are right and it could not be considered a bug, but I still thinking that it is not a consistent behaviour and they should implement a more consistent behaviour as requested in the QC report. Anyway thanks for the clarification about the documentation, I didn't see it ... – aleroot Sep 14 '14 at 08:00
  • It would be better to use FormatSettings.DecimalSeparator instead of ',' – Gerry Coll Sep 15 '14 at 11:21