8
votes

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.

2

2 Answers

6
votes

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.

1
votes

To truncate a value at the nth decimal digit simply multiply it by 10n, truncate the fractional part then divide by 10n again

DivisionOfHeightWidthF := WidthF / HeightF;
DivisionOfHeightWidthF := Trunc(DivisionOfHeightWidthF*100.0)/100.0;

However one problem is that at the truncating step, values that are slightly lower than the integer value will be truncated further down, so you need to get the correct integer with round() before dividing

DivisionOfHeightWidthF := round(int(DivisionOfHeightWidthF*100.0)))/100.0;

Related: How can I round an integer to the nearest 1000 in Pascal?