View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0037374||FPC||RTL||public||2020-07-16 17:09||2020-08-01 19:25|
|Priority||normal||Severity||minor||Reproducibility||have not tried|
|Summary||0037374: FormatFloat broken for exponential format and value 0|
|Description||The output of FormatFloat('0.0E+0', 0) is malformed in FPC 3.2.0 and trunk.|
|Steps To Reproduce||Run this program:|
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(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
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.
|Tags||No tags attached.|
|Fixed in Revision|
The issue occurs not only with the zero but also with "normal" values having a negative exponent:
SysUtils; // FPC 3.2.0, trunk FPC 3.04
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(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(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(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
||The issue is related to 0035297.|
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 ?
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/.
||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.|
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 ..
here is the project , small and simple. you can test run different values if you wish.
project1.zip (131,340 bytes)
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)
|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|