Search code examples
floating-pointintegerinno-setuppascalscript

Round / Truncate floating point numbers to N decimal places in Inno Setup Pascal Script


This does not look like Inno Setup question, but is actually related to its useful Pascal Script.

I wrote a code to do a floating point calculation.

Height, DivisionOfHeightWidth, Width: Integer;

Height := 1080;
Width := 1920;

DivisionOfHeightWidth := Width / Height;
Log('The Division Of Height and Width: ' + IntToStr(DivisionOfHeightWidth));

Compiler log gives the output:

The Division Of Height and Width: 1

I want this compiler output to return this instead:

The Division Of Height and Width: 1.77

I can't declare Height and Width as Extended , Single or Double as they are returning as Integer in most situations, so I need to convert those two Integers to two Singles.

After doing it:

Height, Width: Integer;
HeightF, WidthF, DivisionOfHeightWidthF: Single;

Height := 1080;
Width := 1920;

HeightF := Height;
WidthF := Width;
DivisionOfHeightWidthF := WidthF / HeightF;
Log('The Division Of Height and Width: ' + FloatToStr(DivisionOfHeightWidthF));

Compiler log now gives the output:

The Division Of Height and Width: 1.777777791023

But how can I get this output as 1.77? (Not 1.78 by Rounding) I mean how can I round this 1.777777791023 to two decimal places like 1.77?

If rounding it like 1.77 is impossible to do, how can I round it like 1.78?

Thanks in advance.


Solution

  • If rounding is acceptable, an easy solution is using the Format function:

    var
      Height, Width: Integer;
      DivisionOfHeightWidthF: Single;
    begin
      ...
      DivisionOfHeightWidthF := Single(Width) / Height;
      Log(Format('The Division Of Height and Width: %.2f', [DivisionOfHeightWidthF]));
    end;
    

    For details on the format string, see Delphi documentation for the Format function.

    Note that the Format uses a locale-specific number format (decimal separator particularly).


    If you really need truncating, you need to implement it yourself like:

    var
      Height, Width: Integer;
      DivisionOfHeightWidthF: Single;
      S: string;
      P: Integer;
    begin
      ...
      DivisionOfHeightWidthF := Single(Width) / Height;
      S := FloatToStr(DivisionOfHeightWidthF);
      P := Pos('.', S);
      if P < Length(S) - 2 then
      begin
        SetLength(S, P + 2);
      end;
      Log(S);
    end;
    

    The above works in Unicode Inno Setup only as in Ansi version the FloatToStr uses locale-specific decimal separator, i.e. not always the .. In current Inno Setup 6, the Unicode version is the only version.