Recent

Author Topic: TextToFloat Bug  (Read 5441 times)

Handoko

  • Hero Member
  • *****
  • Posts: 5130
  • My goal: build my own game engine using Lazarus
TextToFloat Bug
« on: January 14, 2018, 11:05:40 am »
I found a bug.

The documentation about TextToFloat says:
Quote
... If the buffer contains a decimal value, then the decimal separator character can either be a '.' or the value of the DecimalSeparator variable.
Source: https://www.freepascal.org/docs-html/rtl/sysutils/texttofloat.html

But my test shows it only uses character of the DecimalSeparator. Tested on Lazarus 1.8.0 FPC 3.0.4 64-bit.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.   end;
  18.  
  19. var
  20.   Form1: TForm1;
  21.  
  22. implementation
  23.  
  24. {$R *.lfm}
  25.  
  26. { TForm1 }
  27.  
  28. procedure TForm1.Button1Click(Sender: TObject);
  29.   Procedure ShowResult(aBoolean: Boolean);
  30.   begin
  31.     case aBoolean of
  32.       True:  ShowMessage('True');
  33.       False: ShowMessage('False');
  34.     end;
  35.   end;
  36. var
  37.   S: PChar;
  38.   R: Extended;
  39. begin
  40.   FormatSettings.DecimalSeparator := '|';
  41.   S := '12|34'; ShowResult(TextToFloat(S, R)); // Result = True
  42.   S := '12.34'; ShowResult(TextToFloat(S, R)); // Result = False
  43. end;
  44.  
  45. end.

Do you think it is a bug of the documentation or the command?
« Last Edit: January 14, 2018, 11:21:30 am by Handoko »

Thaddy

  • Hero Member
  • *****
  • Posts: 14198
  • Probably until I exterminate Putin.
Re: TextToFloat Bug
« Reply #1 on: January 14, 2018, 12:04:32 pm »
Imo it is not a bug at all. You forgot that formatsettings is a global variable of a type TFormatSettings record. You should add a second instance of TFormatSettings if there is a need to change something locally.
Like:
Code: Pascal  [Select][+][-]
  1. program testformatsettings;
  2. uses sysutils;
  3. var
  4.   S: PChar;
  5.   R: Extended;
  6.   MyFormatSettings:TFormatSettings;
  7. begin
  8.   FormatSettings.DecimalSeparator := '|';
  9.   MyFormatSettings := FormatSettings;
  10.   MyFormatSettings.DecimalSeparator :='.';
  11.   S := '12|34'; writeln(TextToFloat(S, R)); // Result = True
  12.   S := '12.34'; writeln(TextToFloat(S, R, MyFormatSettings)); // Result = ? <smile>
  13. end.
  14.  

NAB. It's a BIP.
« Last Edit: January 14, 2018, 12:51:43 pm by Thaddy »
Specialize a type, not a var.

WooBean

  • Full Member
  • ***
  • Posts: 229
Re: TextToFloat Bug
« Reply #2 on: January 14, 2018, 12:44:33 pm »
Hi Handoko,
your observation is correct (tested on Win64, Laz 1.8.0, FPC 3.0.4).

Documentation from link you included contains a demo Example91 which works as aspected in Win64, Laz 1.8.0, FPC 3.0.4. The only "uses" reference is there "SysUtils" but your example uses "Classes, SysUtils, Forms, Dialogs, StdCtrls" and may be even more as we cannot see the project source file. I guess that you are setting FormatSettings.DecimalSeparator global variable somewhere but not this one used by TextToFloat.

Summing up, TextToFloat has no bug.
« Last Edit: January 14, 2018, 12:59:06 pm by WooBean »
Platforms: Win7/64, Linux Mint Ulyssa/64

Thaddy

  • Hero Member
  • *****
  • Posts: 14198
  • Probably until I exterminate Putin.
Re: TextToFloat Bug
« Reply #3 on: January 14, 2018, 12:53:48 pm »
No its is not. Handoko will confirm after my example, that I adapted a little in the mean time to make sure it is the simplest example.
It is not a bug, it is a bug in the programmer not reading the documentation very carefully. Docs are right, code is right, programmer is wrong.

Note that the *exact* example in the manual also simply works: the modification of the global record....
Note maybe a second example like mine above can be added to reflect changes since 2.4.4, but that is just to clarify.

Handoko did not even change the DecimalSeparator, (as per the example) he assumed it would change, which is wrong.
« Last Edit: January 14, 2018, 12:58:52 pm by Thaddy »
Specialize a type, not a var.

Lutz Mändle

  • Jr. Member
  • **
  • Posts: 65
Re: TextToFloat Bug
« Reply #4 on: January 14, 2018, 01:12:45 pm »
The documentation is wrong. According to the actual implementation of TextToFloat only the setting in FormatSettings.DecimalSeparator matters. In very old fpc-2.2.0 it was possible to have a ',' (or whatever) in FormatSettings.DecimalSeparator and a '.' in the text, because that old implemetation only checks for the occurence of the value of FormatSettings.DecimalSeparator in the text and replaces that position (if one) with a '.'. Then val is called which sets the  parameter Value of TextToFloat.
The newer implementation (i could check from fpc-2.4.4 on) forbid this, if a '.' is in the text and the FormatSettings.DecimalSeparator is different then TextToFloat exits with result false.

Thaddy

  • Hero Member
  • *****
  • Posts: 14198
  • Probably until I exterminate Putin.
Re: TextToFloat Bug
« Reply #5 on: January 14, 2018, 01:22:48 pm »
Again: the documentation is right. What has been introduced is an independence on a global formatsettings record, which is still there for compatibility reasons (up until D7 too). And still works.
But if you want to change the behavior like Handoko suggested,, you need a copy and change the copy. This is also Delphi 2005+ compatible. And furthermore it is threadsafe: https://www.freepascal.org/docs-html/rtl/sysutils/tformatsettings.html

You are confusing new language features with perceived current behavior: that is wrong anyway.
If the documentation is not completely clear for somebody - it is to me - ask for clarification and file a bug-report towards documentation and ask Michael to explain it a bit more in-depth.
Note this is also all in the release notes.

And please read - and test - my example before you write nonsense: it is self-explanatory and written with simple in mind, so it should not only fit Handoko (who will understand all this) but also for simple minds.
« Last Edit: January 14, 2018, 01:36:06 pm by Thaddy »
Specialize a type, not a var.

Lutz Mändle

  • Jr. Member
  • **
  • Posts: 65
Re: TextToFloat Bug
« Reply #6 on: January 14, 2018, 01:34:10 pm »
You miss the point. The documentation says:

If the buffer contains a decimal value, then the decimal separator character can either be a '.' or the value of the DecimalSeparator variable.

That implies for me and other readers that it is possible to have whatever in the global FormatSettings and have a '.' in the text given to TextToFloat in that calling variant without FormatSettings. Then the global FormatSettings rule and the actual implementation forbids that. The old implementation was allowing that.
For me the actual behaviour is fine, it is more strict, but the documentation should not say that the decimal separator character (in the given text) can either be a '.' or the value of the DecimalSeparator variable.

Thaddy

  • Hero Member
  • *****
  • Posts: 14198
  • Probably until I exterminate Putin.
Re: TextToFloat Bug
« Reply #7 on: January 14, 2018, 01:39:02 pm »
You miss the point. The documentation says:

If the buffer contains a decimal value, then the decimal separator character can either be a '.' or the value of the DecimalSeparator variable.

That implies for me and other readers that it is possible to have whatever in the global FormatSettings and have a '.' in the text given to TextToFloat in that calling variant without FormatSettings. Then the global FormatSettings rule and the actual implementation forbids that. The old implementation was allowing that.
For me the actual behaviour is fine, it is more strict, but the documentation should not say that the decimal separator character (in the given text) can either be a '.' or the value of the DecimalSeparator variable.
It should, because that is the behavior for currency type (which uses an international standard). Again: docs are correct. Doesn't hurt to ask for additional documentation, however.
Specialize a type, not a var.

Handoko

  • Hero Member
  • *****
  • Posts: 5130
  • My goal: build my own game engine using Lazarus
Re: TextToFloat Bug
« Reply #8 on: January 14, 2018, 01:52:08 pm »
Hi Handoko,
your observation is correct (tested on Win64, Laz 1.8.0, FPC 3.0.4).

Documentation from link you included contains a demo Example91 which works as aspected in Win64, Laz 1.8.0, FPC 3.0.4. The only "uses" reference is there "SysUtils" but your example uses "Classes, SysUtils, Forms, Dialogs, StdCtrls" and may be even more as we cannot see the project source file. I guess that you are setting FormatSettings.DecimalSeparator global variable somewhere but not this one used by TextToFloat.

Summing up, TextToFloat has no bug.

My regional setting show that I'm using ",". And below is the source I used for the test.

Lutz Mändle

  • Jr. Member
  • **
  • Posts: 65
Re: TextToFloat Bug
« Reply #9 on: January 14, 2018, 01:53:52 pm »
The given documentation gives no clue that it has something to do with currency type.

But I've examined the implementations of TextToFloat back to FPC 2.2.0 (that was 2007) and that old version allows what Handokos example want. The newer implementations (at least FPC 2.4.4 in 2011, maybe earlier) were forbidding this.

wp

  • Hero Member
  • *****
  • Posts: 11854
Re: TextToFloat Bug
« Reply #10 on: January 14, 2018, 01:55:04 pm »
Command is fine, but documentation is wrong, at least highly misleading. When I read "decimal separator character can either be a '.' or the value of the DecimalSeparator variable" I can conclude that I can type in "1.2" or "1,2" and will always get a correct conversion to float. (',' is my decimal separator). Like in TFloatSpinEdit, where both decimal separators can be used without any other changes.

The documentation should be changed to something like this:

"If the buffer contains a decimal value, then the decimal separator defined by the sysutils FormatSettings must be used. Alternatively any other decimal separator is accepted if it is specified in a local copy of the formatsettings passed as an additional parameter."

WooBean

  • Full Member
  • ***
  • Posts: 229
Re: TextToFloat Bug
« Reply #11 on: January 14, 2018, 02:02:05 pm »
Topic: TextToFloat Bug leads me to Lazarus IDE (Win64, Laz 1.8.0, FPC 3.0.4) usage question.
I would like to find all occurences of "FormatSettings" literals in all project files (*.pas and *.inc).
Simple action  via popup menu "Find->Find in Files" and option "Where / search all files in project" shows only occurences in Unit1 (value is used here but not declared). What I am doing wrong?
Platforms: Win7/64, Linux Mint Ulyssa/64

Handoko

  • Hero Member
  • *****
  • Posts: 5130
  • My goal: build my own game engine using Lazarus
Re: TextToFloat Bug
« Reply #12 on: January 14, 2018, 02:07:16 pm »
Okay, lets try not to use Lazarus IDE.

I now use FP (text mode IDE) on the Terminal. Here is what I got running the example "Example9"1 provided by the documentation. Do you get the same?

wp

  • Hero Member
  • *****
  • Posts: 11854
Re: TextToFloat Bug
« Reply #13 on: January 14, 2018, 02:12:58 pm »
"Search all files in projects" only searches the files that are listed in the project inspector underneath the project node. If there's only "project1.lpr" and "unit1" (the default of a new project), then only these will be searched. In order to find the declarations etc. you must select "search  in directories" and specifiy the fpc source directory.

A faster way to find the declaration: Hold CTRL down while you click on "FormatSettings", and the source editor will open the unit in which "FormatSettings" is declared (or implemented - depends on the version and what is being searched for). Press SHIFT+UP or SHIFT+DOWN to toggle between interface and implementation of functions.

Handoko

  • Hero Member
  • *****
  • Posts: 5130
  • My goal: build my own game engine using Lazarus
Re: TextToFloat Bug
« Reply #14 on: January 14, 2018, 02:18:28 pm »
Now I tested again with the same previous code but with some modification:

Code: Pascal  [Select][+][-]
  1. TestStr : Array[1..NrValues] of pchar =
  2.            ('1.1','-0.2','1.2E-4','0','1E4');

The whole source code:
Code: Pascal  [Select][+][-]
  1. Program Test;
  2.  
  3. { This program demonstrates the TextToFloat function }
  4. {$mode objfpc}
  5. {$h+ }
  6.  
  7. Uses SysUtils;
  8.  
  9. Const
  10.   NrValues = 5;
  11.   TestStr : Array[1..NrValues] of pchar =
  12.            ('1.1','-0.2','1.2E-4','0','1E4');
  13.  
  14. Procedure Testit;
  15.  
  16. Var
  17.   I : Integer;
  18.   E : Extended;
  19.  
  20. begin
  21.   Writeln('Using DecimalSeparator : ',DecimalSeparator);
  22.   For I:=1 to NrValues do
  23.     begin
  24.     Writeln('Converting : ',TestStr[i]);
  25.     If TextToFloat(TestStr[i],E) then
  26.       Writeln('Converted value : ',E)
  27.     else
  28.       Writeln('Unable to convert value.');
  29.     end;
  30. end;
  31.  
  32. Begin
  33.   DecimalSeparator:=',';
  34.   Testit;
  35.   DecimalSeparator:='.';
  36.   Testit;
  37. End.

Tested on Free Pascal IDE x86-64 FPC 3.0.4. From the source above you can clearly see it only uses SysUtils.

 

TinyPortal © 2005-2018