View Issue Details

IDProjectCategoryView StatusLast Update
0037374FPCRTLpublic2020-08-01 19:25
Reporterwp Assigned To 
PrioritynormalSeverityminorReproducibilityhave not tried
Status newResolutionopen 
Platformx86OSWindows 
Product Version3.2.0 
Summary0037374: FormatFloat broken for exponential format and value 0
DescriptionThe output of FormatFloat('0.0E+0', 0) is malformed in FPC 3.2.0 and trunk.
Steps To ReproduceRun this program:

program Project1;
uses
  SysUtils;
begin
  WriteLn(FormatFloat('0.0E+00', 0)); // Output: '0.0E--1' --> "ugly"
  WriteLn(FormatFloat('0.0E-00', 0)); // Output: '0.0E--1' --> "ugly"
  WriteLn(FormatFloat('0.0E00', 0)); // Output: '0.0E0' ---> correct
  WriteLn;
  WriteLn(FormatFloat('0.0E+0', 0)); // Output: '0.0E--1' --> "ugly"
  WriteLn(FormatFloat('0.0E-0', 0)); // Output: '0.0E--1' --> "ugyl"
  WriteLn(FormatFloat('0.0E0', 0)); // Output: '0.0E0' ---> correct

  ReadLn;
end.

The output is indicated in the comments. In the lines marked as "ugly" I'd expect the output to be '0.0E+00' or '0.0E+0'.

Older versions of FPC (3.0.4) produce the expected output.
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Activities

wp

2020-07-17 23:37

reporter   ~0124133

The issue occurs not only with the zero but also with "normal" values having a negative exponent:

program Project1;
uses
  SysUtils; // FPC 3.2.0, trunk FPC 3.04
begin
  WriteLn(FormatFloat('0.0E+0000', 0.1)); // --> 1.0E-00-1 1.0E-0001
  WriteLn(FormatFloat('0.0E+0000', 0.002)); // --> 2.0E-00-3 2.0E-0003
  WriteLn(FormatFloat('0.0E+0000', -0.0045)); // --> -4.5E-00-3 4.5E-0003
  WriteLn;
  WriteLn(FormatFloat('0.0E+000', 0.1)); // --> 1.0E-0-1 1.0E-001
  WriteLn(FormatFloat('0.0E+000', 0.002)); // --> 2.0E-0-3 2.0E-003
  WriteLn(FormatFloat('0.0E+000', -0.0045)); // --> -4.5E-0-3 -4.5E-003
  WriteLn;
  WriteLn(FormatFloat('0.0E+00', 0.1)); // --> 1.0E--1 1.0E-01
  WriteLn(FormatFloat('0.0E+00', 0.002)); // --> 2.0E--3 2.0E-03
  WriteLn(FormatFloat('0.0E+00', -0.0045)); // --> -4.5E--3 -4.5E-03
  WriteLn;
  WriteLn(FormatFloat('0.0E+0', 0.1)); // --> 1.0E--1 1.0E-1
  WriteLn(FormatFloat('0.0E+0', 0.002)); // --> 2.0E--3 2.0E-3
  WriteLn(FormatFloat('0.0E+0', -0.0045)); // --> -4.5E--3 -4.5E-3
end.

wp

2020-07-18 19:30

reporter   ~0124150

The issue is related to 0035297.

jamie philbrook

2020-07-19 03:45

reporter   ~0124163

Last edited: 2020-07-19 03:47

View 2 revisions

I copy the mean core of that code over to a Lazarus project that handles that part in fpc and I have to tell you that code is pretty much messed up. Not only that it is taking lots of cpu time to process what should be a simple matter.

 I found where the double -- were coming from and that was due to not using a ABS call around a Inttostr conversion.
   
 But there is the issue with the multiplier not resolving the string properly..

 was there something wrong with the code in 3.0.4 ? that works and it works well, why was that taken out ?

jamie philbrook

2020-07-19 23:28

reporter   ~0124176

This code is hard to follow however, I took the source of fmtflt.inc and moved it into a Lazarus project. Added the required calls to simulate the real operation.
 
 I made changes to the Function FormatExpenent(….) where by it had multiple issues.

 I also added one ELSE branch in the main loop to account for non scientific digits because I was coming up short by one digit.

 It seems to product the expected results. I can post the project here for any one to look at it if they wish otherwise I'll just archive it.
 I am sure the author of that code may have a better way to fix it , I just tried to stay with what was there.
  
 Let me know if interested in the project I have. I did in the latest release of Lazarus 2.10-64 bit/.

wp

2020-07-20 01:02

reporter   ~0124177

Jamie, when you have a fix you should submit it as a proper patch (relative to current fpc trunk) because this shows the differences between old and your code. I don't think that FPC devs are willing to analyze your project in any depth to extract the relevant parts.

jamie philbrook

2020-07-20 01:14

reporter   ~0124178

They don't have too pick at it. Its the same exact code that is in the fpc now.. I just copy and pasted it over to my project and called it the same wall..

  They can do the same in reverse if they like, it will link in without any changes

 One function is the complete INC file that is problematic and that is what I did, move that complete file over as a single function and fixed it.

 This is from the recent release of 2.10. Anyways. I thought maybe someone would like to look at it first and then decide if its worthy of summiting ..

jamie philbrook

2020-07-20 01:18

reporter   ~0124179

here is the project , small and simple. you can test run different values if you wish.
project1.zip (131,340 bytes)

wp

2020-07-22 23:32

reporter   ~0124242

Good job, jamie.

I extracted the patch from jamie's project (--> fmtflt.inc.patch, relative to fpc trunk), and I wrote a test project (formatfloat_test) with all cases that came to my mind (126 tests) -- all of them are passed. Hopefully somebody from the fpc team picks this up soon.
fmtflt.inc.patch (1,070 bytes)   
Index: rtl/objpas/sysutils/fmtflt.inc
===================================================================
--- rtl/objpas/sysutils/fmtflt.inc	(revision 45824)
+++ rtl/objpas/sysutils/fmtflt.inc	(working copy)
@@ -298,11 +298,12 @@
   Function FormatExponent(ASign: FChar; aExponent: Integer) : FString;
 
   begin
-    Result:=IntToStr(aExponent);
+    If E = 0 then aExponent := 0;
+    Result:=IntToStr(Abs(aExponent));
     Result:=StringOfChar('0',ExpSize-Length(Result))+Result;
-    if (aExponent<0) then
+    if (aExponent < 0 ) then
       Result:='-'+Result
-    else if (aExponent>0) and (aSign='+') then
+    else if (aExponent>=0) and (aSign='+') then
       Result:=aSign+Result;
   end;
 
@@ -383,7 +384,11 @@
                 Inc(I);
               end;
             end;
-          end;  
+          end else if I< SectionLength Then
+            Begin
+             inc(I);
+             ToResult(Section[i]);
+            end;
         end;
       else
         ToResult(C);
@@ -392,4 +397,3 @@
     end;
 //  Writeln('Result  ',Result);
 end;
-
fmtflt.inc.patch (1,070 bytes)   
formatfloat_test.zip (1,711 bytes)

wp

2020-08-01 19:25

reporter   ~0124468

ping...

Issue History

Date Modified Username Field Change
2020-07-16 17:09 wp New Issue
2020-07-17 23:37 wp Note Added: 0124133
2020-07-18 19:30 wp Note Added: 0124150
2020-07-19 03:45 jamie philbrook Note Added: 0124163
2020-07-19 03:47 jamie philbrook Note Edited: 0124163 View Revisions
2020-07-19 23:28 jamie philbrook Note Added: 0124176
2020-07-20 01:02 wp Note Added: 0124177
2020-07-20 01:14 jamie philbrook Note Added: 0124178
2020-07-20 01:18 jamie philbrook Note Added: 0124179
2020-07-20 01:18 jamie philbrook File Added: project1.zip
2020-07-22 23:32 wp Note Added: 0124242
2020-07-22 23:32 wp File Added: fmtflt.inc.patch
2020-07-22 23:32 wp File Added: formatfloat_test.zip
2020-08-01 19:25 wp Note Added: 0124468