Recent

Author Topic: FloattostrF, number of digits is unpredictable if TFloatformat is FFGeneral  (Read 668 times)

han

  • Full Member
  • ***
  • Posts: 117
I have some problems with floattostrF. I see the following behaviour:

  test:=floattostrF(0.99111,FFFixed,0,1);//=> 1.0

   test:=floattostrF(0.99111,FFgeneral,0,4);//=> 0.99
   test:=floattostrF(0.99111,FFgeneral,0,3);//=> 0.99
   test:=floattostrF(0.99111,FFgeneral,0,2);//=>0.99
   test:=floattostrF(0.99111,FFgeneral,0,1);//=> 0.99
   test:=floattostrF(0.99111,FFgeneral,0,0); //=> 0.99
 

Maybe I'm wrong, but I would expect that

   floattostrF(0.99111,FFgeneral,0,1)

would produce a string '1'. Why is it producing 0.99?

More tests. Rounding  less then 2 decimals seems not possible. How to round to one decimal behind the decimal separator?

   test:=floattostrF(0.9911,FFgeneral,0,4);//=> 0.99  rounding to two decimals
   test:=floattostrF(0.9911,FFgeneral,0,3);//=> 0.99
   test:=floattostrF(0.9911,FFgeneral,0,2);//=> 0.99
   test:=floattostrF(0.9911,FFgeneral,0,1);//=> 0.99
   test:=floattostrF(0.9911,FFgeneral,0,0);//=> 0.99

   test:=floattostrF(0.9911,FFgeneral,1,4);//=> 0.99   rounding to two decimals
   test:=floattostrF(0.9911,FFgeneral,1,3);//=> 0.99
   test:=floattostrF(0.9911,FFgeneral,1,2);//=> 0.99
   test:=floattostrF(0.9911,FFgeneral,1,1);//=> 0.99
   test:=floattostrF(0.9911,FFgeneral,1,0);//=> 0.99

   test:=floattostrF(0.9911,FFgeneral,2,4);//=> 0.99    rounding to two decimals
   test:=floattostrF(0.9911,FFgeneral,2,3);//=> 0.99
   test:=floattostrF(0.9911,FFgeneral,2,2);//=> 0.99
   test:=floattostrF(0.9911,FFgeneral,2,1);//=> 0.99
   test:=floattostrF(0.9911,FFgeneral,2,0);//=> 0.99

   test:=floattostrF(0.9911,FFgeneral,3,4);//=> 0.991   three decimals
   test:=floattostrF(0.9911,FFgeneral,3,3);//=> 0.991
   test:=floattostrF(0.9911,FFgeneral,3,2);//=> 0.991
   test:=floattostrF(0.9911,FFgeneral,3,1);//=> 0.991
   test:=floattostrF(0.9911,FFgeneral,3,0);//=> 0.991



   test:=floattostrF(0.98511,FFgeneral,0,4);//=> 0.99   rounding to two decimals
   test:=floattostrF(0.98511,FFgeneral,0,3);//=> 0.99
   test:=floattostrF(0.98511,FFgeneral,0,2);//=> 0.99
   test:=floattostrF(0.98511,FFgeneral,0,1);//=> 0.99
   test:=floattostrF(0.98511,FFgeneral,0,0);//=> 0.99

   test:=floattostrF(0.98511,FFgeneral,1,4);//=> 0.99   rounding to two decimals
   test:=floattostrF(0.98511,FFgeneral,1,3);//=> 0.99
   test:=floattostrF(0.98511,FFgeneral,1,2);//=> 0.99
   test:=floattostrF(0.98511,FFgeneral,1,1);//=> 0.99
   test:=floattostrF(0.98511,FFgeneral,1,0);//=> 0.99

   test:=floattostrF(0.98511,FFgeneral,2,4);//=> 0.99    rounding to two decimals
   test:=floattostrF(0.98511,FFgeneral,2,3);//=> 0.99
   test:=floattostrF(0.98511,FFgeneral,2,2);//=> 0.99
   test:=floattostrF(0.98511,FFgeneral,2,1);//=> 0.99
   test:=floattostrF(0.98511,FFgeneral,2,0);//=> 0.99

   test:=floattostrF(0.98511,FFgeneral,3,4);//=> 0.985   three decimals
   test:=floattostrF(0.98511,FFgeneral,3,3);//=> 0.985
   test:=floattostrF(0.98511,FFgeneral,3,2);//=> 0.985
   test:=floattostrF(0.98511,FFgeneral,3,1);//=> 0.985
   test:=floattostrF(0.98511,FFgeneral,3,0);//=> 0.985



Han

« Last Edit: July 30, 2024, 12:53:09 am by han »

jamie

  • Hero Member
  • *****
  • Posts: 6516
because ROUND is being used ?
The only true wisdom is knowing you know nothing

han

  • Full Member
  • ***
  • Posts: 117
See my update in the first post. My problem is that I want convert floats to a string with one decimal behind the decimal separator.  It seems that less then two decimals is not possible. Secondly only the value precision seems to do something for FFGeneral. Digits does not do anything.

TRon

  • Hero Member
  • *****
  • Posts: 3129
@han you might perhaps be interested in example68 which accompanies the documentation on FloatToStrF.

If you adjust that to meet your needs then it produces about 40k output and shows the difference in behaviour between the different floatformats.
All software is open source (as long as you can read assembler)

wp

  • Hero Member
  • *****
  • Posts: 12279
I never use FloatToStrF... I would do it as Format('%.1f', [0.99111]) or as FormatFloat('0.0', 0.99111).

jamie

  • Hero Member
  • *****
  • Posts: 6516
it seems to work better if you use a DOUBLE instead of the constant.

I see a mark difference in behavior.
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6516
Code: Pascal  [Select][+][-]
  1.  
  2. procedure TForm1.Button1Click(Sender: TObject);
  3. Var
  4.   F:Double;
  5. begin
  6.   F:= 0.99106;
  7.   Caption := Double(Trunc(F * 10) / 10).Tostring;
  8. end;                                            
  9.  

Generates 0.9
The only true wisdom is knowing you know nothing

han

  • Full Member
  • ***
  • Posts: 117
For a graph scale,  I intended to display 1.0 as 1

Thanks, your solution produces also 1 for input 0.991 but it should rounded like this:

Code: Pascal  [Select][+][-]
  1. Caption := Double(Round(F * 10) / 10).Tostring;

But this also works perfect:

Code: Pascal  [Select][+][-]
  1.   scale:=0.99111;
  2.   test:=FormatFloat('0.#', scale); //=> 1
  3.  
  4.   scale:=1.151;
  5.   test:=FormatFloat('0.#', scale);// => 1.2

This doesn't seems possible with floattoStrF.

« Last Edit: July 30, 2024, 12:01:38 pm by han »

han

  • Full Member
  • ***
  • Posts: 117
I checked the behaviour of floattostrF in Delphi XE6 and it is identical to FPC. With Tfloatformat=FFgeneral you can specify the number or decimals with the parameter precision but not lower then 2 decimals. The parameter digits isn't doing anything.  Must have been written for coding financial transactions.

han

  • Full Member
  • ***
  • Posts: 117
Thanks all for replying. Now all clear. The minimum precision is 2, not lower:

Code: Pascal  [Select][+][-]
  1.  F:=0.99411;
  2.      test:=floattostrF(F,FFgeneral,0,0);//=> 0.99,
  3.      test:=floattostrF(F,FFgeneral,1,0);//=> 0.99
  4.      test:=floattostrF(F,FFgeneral,2,0);//=> 0.99
  5.      test:=floattostrF(F,FFgeneral,3,0);//=> 0.994
  6.  
  7.  
  8.    F:=0.99511;
  9.    test:=floattostrF(F,FFgeneral,0,0);//=> 1
  10.    test:=floattostrF(F,FFgeneral,1,0);//=> 1
  11.    test:=floattostrF(F,FFgeneral,2,0);//=> 1
  12.    test:=floattostrF(F,FFgeneral,3,0);//=> 0.995
  13.  
  14.  
  15.    F:=12.145;
  16.     test:=floattostrF(F,FFgeneral,0,0);//=> 12
  17.     test:=floattostrF(F,FFgeneral,1,0);//=> 12
  18.     test:=floattostrF(F,FFgeneral,2,0);//=> 12
  19.     test:=floattostrF(F,FFgeneral,3,0);//=> 12.1
  20.     test:=floattostrF(F,FFgeneral,4,0);//=> 12.15
  21.     test:=floattostrF(F,FFgeneral,5,0);//=> 12.145  
« Last Edit: July 30, 2024, 09:35:08 pm by han »

 

TinyPortal © 2005-2018