Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 605
GTAVLover Avatar asked Aug 16 '16 04:08

GTAVLover


1 Answers

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.

like image 122
Martin Prikryl Avatar answered Oct 03 '22 19:10

Martin Prikryl