Explorar o código

* fixed FloatToStr for ffGeneral when dealing with numbers whose number of
significant digits before the decimal points matches the precision
parameter exactly (mantis #16188)
* round instead of cut off digits in FloatToStr with ffGeneral
* take into account the minus sign when determining whether a number needs
to be represented using ffExponent instead of ffGeneral because it has
too many digits

git-svn-id: trunk@15114 -

Jonas Maebe %!s(int64=15) %!d(string=hai) anos
pai
achega
a18f2594e2
Modificáronse 3 ficheiros con 73 adicións e 9 borrados
  1. 1 0
      .gitattributes
  2. 10 9
      rtl/objpas/sysutils/sysstr.inc
  3. 62 0
      tests/webtbs/tw16188.pp

+ 1 - 0
.gitattributes

@@ -10344,6 +10344,7 @@ tests/webtbs/tw16083.pp svneol=native#text/plain
 tests/webtbs/tw16108.pp svneol=native#text/plain
 tests/webtbs/tw16163.pp svneol=native#text/plain
 tests/webtbs/tw1617.pp svneol=native#text/plain
+tests/webtbs/tw16188.pp svneol=native#text/plain
 tests/webtbs/tw1622.pp svneol=native#text/plain
 tests/webtbs/tw1623.pp svneol=native#text/plain
 tests/webtbs/tw1634.pp svneol=native#text/plain

+ 10 - 9
rtl/objpas/sysutils/sysstr.inc

@@ -1197,10 +1197,11 @@ Begin
             else
               Str(Extended(Value):0:precision, Result);
           end;
+          Negative := Result[1] = '-';
           P := Pos('.', Result);
           if P<>0 then
             Result[P] := DS;
-          TooLarge :=(P > Precision + 1) or (Pos('E', Result)<>0);
+          TooLarge :=(P > Precision + ord(Negative) + 1) or (Pos('E', Result)<>0);
         End;
 
         If TooSmall Or TooLarge Then
@@ -1231,14 +1232,14 @@ Begin
             { significant digits" rather than "number of digits after the }
             { decimal point" (as it does in the system unit) -> adjust    }
             { (precision+1 to count the decimal point character)          }
-            if Result[1] = '-' then
-              Inc(Precision);
-            if (Length(Result) > Precision + 1) and
-               (Precision + 1 > P) then
-              begin
-                P := Precision + 1;
-                SetLength(Result,P);
-              end;
+            { don't just cut off the string, as rounding must be taken    }
+            { into account based on the final digit                       }
+            
+            if (Length(Result) > Precision + ord(Negative) + 1) and
+               (Precision + ord(Negative) + 1 >= P) then
+              Result := FloatToStrFIntl(Value, ffFixed,
+                0, Precision - (P - Ord(Negative) - 1),
+                ValueType, FormatSettings);
             P := Length(Result);
             While (P>0) and (Result[P] = '0') Do
               Dec(P);

+ 62 - 0
tests/webtbs/tw16188.pp

@@ -0,0 +1,62 @@
+uses
+  SysUtils;
+
+const
+  results: array[1..16] of string = 
+(
+'234.6',
+'234.57',
+'234.568',
+'1000',
+'1235',
+'1234.6',
+'1234.57',
+'1234.568',
+'-234.6',
+'-234.57',
+'-234.568',
+'-1000',
+'-1235',
+'-1234.6',
+'-1234.57',
+'-1234.568'
+);
+
+procedure check(const s: string; index: longint);
+begin
+  if (s<>results[index]) then
+    begin
+      writeln('Expected : ',results[index]);
+      writeln('Got      : ',s);
+      halt(1);
+    end;
+end;
+
+var ext:extended;
+  str: shortstring;
+begin
+  ext:=234.56789; 
+  check(FloatToStrF(ext,ffGeneral,4,1),1);
+  check(FloatToStrF(ext,ffGeneral,5,1),2);
+  check(FloatToStrF(ext,ffGeneral,6,7),3);
+  ext:=999.9999;
+  check(FloatToStrF(ext,ffGeneral,4,7),4);
+  ext:=1234.56789;
+  check(FloatToStrF(ext,ffGeneral,4,1),5);
+  check(FloatToStrF(ext,ffGeneral,5,1),6);
+  check(FloatToStrF(ext,ffGeneral,6,1),7);
+  check(FloatToStrF(ext,ffGeneral,7,1),8);
+
+  ext:=-234.56789; 
+  check(FloatToStrF(ext,ffGeneral,4,1),9);
+  check(FloatToStrF(ext,ffGeneral,5,1),10);
+  check(FloatToStrF(ext,ffGeneral,6,7),11);
+  ext:=-999.9999;
+  check(FloatToStrF(ext,ffGeneral,4,7),12);
+  ext:=-1234.56789;
+  check(FloatToStrF(ext,ffGeneral,4,1),13);
+  check(FloatToStrF(ext,ffGeneral,5,1),14);
+  check(FloatToStrF(ext,ffGeneral,6,1),15);
+  check(FloatToStrF(ext,ffGeneral,7,1),16);
+end.
+