diff --git a/packages/rtl/sysutils.pas b/packages/rtl/sysutils.pas index 605d805..dcc7bb2 100644 --- a/packages/rtl/sysutils.pas +++ b/packages/rtl/sysutils.pas @@ -33,7 +33,7 @@ type TFloatRec = Record Exponent: Integer; Negative: Boolean; - Digits: Array Of Char; + Digits: Array[0..18] Of Char; End; TEndian = (Little,Big); TFileName = String; @@ -673,20 +673,21 @@ end; Function FloatToDecimal(Value : double; Precision, Decimals : integer) : TFloatRec; Const - Rounds = '234567890'; + Rounds = '1234567890'; var Buffer: String; //Though str func returns only 25 chars, this might change in the future InfNan: string; - Error, N, L, Start, C: Integer; + OutPos,Error, N, L, Start, C: Integer; GotNonZeroBeforeDot, BeforeDot : boolean; begin - if Value=0 then ; - SetLength(Result.Digits,19); + if Value=0 then + exit; asm Buffer=Value.toPrecision(21); // Double precision end; + // Writeln('Buffer :',Buffer); N := 1; L := Length(Buffer); while Buffer[N]=' ' do @@ -714,47 +715,51 @@ begin end; end; Start := N; //Start of digits + Outpos:=0; Result.Exponent := 0; BeforeDot := true; GotNonZeroBeforeDot := false; while (L>=N) and (Buffer[N]<>'E') do begin + // Writeln('Examining : ',Buffer[N],'( output pos: ',outPos,')'); if Buffer[N]='.' then BeforeDot := false else begin - if BeforeDot then - begin // Currently this is always 1 char - Inc(Result.Exponent); - Result.Digits[N-Start] := Buffer[N]; - if Buffer[N] <> '0' then - GotNonZeroBeforeDot := true; - end - else - Result.Digits[N-Start-1] := Buffer[N] + if BeforeDot then + begin // Currently this is always 1 char + Inc(Result.Exponent); + Result.Digits[Outpos] := Buffer[N]; + if Buffer[N] <> '0' then + GotNonZeroBeforeDot := true; + end + else + Result.Digits[Outpos] := Buffer[N]; + Inc(outpos); end; Inc(N); end; - Inc(N); // Pass through 'E' - if N<=L then - begin - Val(Copy(Buffer, N, L-N+1), C, Error); // Get exponent after 'E' - Inc(Result.Exponent, C); - end; - // Calculate number of digits we have from str - if BeforeDot then - N := N - Start - 1 - else - N := N - Start - 2; - L := Length(Result.Digits); - if N= L Then - N := L-1; + Inc(N); // Pass through 'E' + if N<=L then + begin + Val(Copy(Buffer, N, L-N+1), C, Error); // Get exponent after 'E' + Inc(Result.Exponent, C); + end; + // Calculate number of digits we have from str + N:=OutPos; +// Writeln('Number of digits: ',N,' requested precision : ',Precision); + L:=Length(Result.Digits); + While N= L Then + N := L-1; +// Writeln('Rounding on digit : ',N); if N = 0 Then begin if Result.Digits[0] >= '5' Then @@ -774,9 +779,9 @@ begin Result.Digits[N] := #0; Dec(N); // Writeln(N,': ',Result.Digits[N],', Rounding to : ',Rounds[StrToInt(Result.Digits[N])]); - Result.Digits[N]:=Rounds[StrToInt(Result.Digits[N])]; + Result.Digits[N]:=Rounds[StrToInt(Result.Digits[N])+1]; Until (N = 0) Or (Result.Digits[N] < ':'); - If Result.Digits[0] = ':' Then + If Result.Digits[0] = '0' Then begin Result.Digits[0] := '1'; Inc(Result.Exponent); @@ -925,7 +930,7 @@ var // Will return '0' if applicable. begin - // Writeln(' DistToDecimal <= LastDigit : ',DistToDecimal,' < ',LastDigit,' have digit: ',Current<=Available, '(',Current,')'); + // Writeln(' DistToDecimal <= LastDigit : ',DistToDecimal,' <= ',LastDigit,' have digit: ',Current<=Available, ' (',Current,')'); Result:=#0; if (Current<=Available) then begin @@ -936,7 +941,7 @@ var Dec(DistToDecimal) else Result:='0'; - // Writeln('GetDigit ->: ',Result); + // Writeln('GetDigit ->: ',Result); end; procedure CopyDigit; @@ -1112,6 +1117,9 @@ var D:=RequestedDigits-DecimalPos+1; end; FV:=FloatToDecimal(aValue,P,D); + // Writeln('Number of digits available : ',Length(FV.Digits)); + // For p:=0 to Length(FV.Digits)-1 do + // writeln(P,': ',FV.Digits[p]); DistToDecimal:=DecimalPos-1; if IsScientific then PadZeroes:=0 // No padding.