# Delphi/Lazarus: 3 Ways to round a Number to X Decimal Places

Tutorial by Stefan Trost | Last update on 2024-04-12 | Created on 2014-02-19

Most users of Delphi or also Lazarus are thinking about the function Round() when it is about rounding a number. Unfortunately, this function cannot be used to keep some of the decimal places of the original value. Using Round(), you can only make 1 from the number 1.2345 but you are not able to round this value to one (1.2), two (1.23), three (1.235) or more decimal places.

But you can do it in another way. In this tutorial I would like to show you how you can achieve it without the standard Round() function in Delphi or Lazarus.

In the following, we have a look at the following three possibilities to do this:

## RoundTo

The easiest way is to use the function RoundTo() included in the Unit Math (so you just need to add "Math" to your uses section in order to be able to use this function). Here is an example of how to use this function:

```k := 1.2345;
k := RoundTo(k, -2);  // k = 1.23```

As a first parameter, we can pass our number we would like to round, as a second parameter the number of decimal places, we would like to keep.

Important: Our desired decimal places have to be specified as a negative value (in our example -2 for two decimal places). The background: RoundTo() uses negative versus positive values of the second parameter to make it possible to specify different types of rounding. Negative values are used by the function to specify roundings to places after the decimal point. Positive values, on the other hand, are used to specify roundings not according to a number of decimal places but to places before the decimal point. That is, for example, to hundreds or thousands. Examples of this would be "RoundTo(12345, 2) = 12300" or "RoundTo(12345, 4) = 10000".

## Own Function

It is possible, that older versions of the IDE are not supporting the RoundTo() method yet. In this case, we can alternatively also just use the following calculation to get to our rounded result on our own:

```x := 1.2345;
k := round(x * 100) / 100;    // 1.23
k := round(x * 1000) / 1000;  // 1.235```

Generalized and swapped out as a function results in the following code:

```function RoundEx(const AInput: extended; APlaces: integer): extended;
var
k: extended;
begin
k := power(10, APlaces);
result := round(AInput * k) / k;
end;
```

We only have to pass our value as well as the number of desired decimal places to this function and we can then use it just the same way as RoundTo().

However, with the exception that, in contrast to RoundTo(), this function is only designed for rounding behind the decimal point. Therefore, in this Rounding Tutorial for Delphi and Lazarus I have introduced an extension of this function. With the function presented there, you are able to round in both directions: you can round to an arbitrary number of decimal places as well as to positions before the decimal point. This would give us a complete replacement for RoundTo().

## Output directly as String

As a third method for getting arbitrarily rounded numbers, I don't want to withhold the possibility to output a floating point number directly rounded as a string:

```x := 1.2345;
s := FormatFloat('0.00', x);           // 1.23
s := FormatFloat('0.000', x);          // 1.235
s := FormatFloat('0.000000', x);       // 1.234500
s := FormatFloat('0.######', x);       // 1.2345
s := FloatToStrF(x, ffFixed, 2, 2);    // 1.23
s := FloatToStrF(x, ffFixed, 3, 3);    // 1.235
s := FloatToStrF(x, ffFixed, 4, 6);    // 1.234500
```

For this, we can, for example, use the functions FormatFloat or FloatToStrF. The code shows some usage examples for both functions.

FormatFloat accepts the format as a first parameter and the number as a second parameter. When using a "0" in the format string, this digit is outputted in each case, when using a hash "#", this digit is outputted only if necessary. The examples show how we can use these features to round the number passed.

FloatToStrF is providing many possibilities to format a number in various ways. In our case, for rounding, it is sufficient, to pass the value to be rounded as a first parameter (Value) and the number of desired decimal places as a last parameter (Digits), as it is shown in the last three lines of the example code. The second parameter (Format) can be used to determine the format. For our purposes, "ffFixed" (fixed point format) is the best choice. If we need thousands separators, we can alternatively also use “ffNumber” instead. The third parameter (Precision) stands for the precision. If the specified precision is chosen smaller than the desired number of decimal places determined via the Digits parameter (as in the last example), the additional places are filled with zeros.

"k := RoundTo(k, 2); // k = 1.23",

should be

"k := RoundTo(k, -2); // k = 1.23".
2016-01-22 at 08:40

Thank you very much for this note.

I have corrected the example and wrote something about the difference between negative and positive values.
2016-01-23 at 14:10

Positive Negative

There still seems to be a lack of a general purpose function to set the number of digits after the decimal point.

A 2 digit round off should work with all values not just numbers within a small range.

eg. 1.29343e-6 should round to 1.29e-6

It should do nothing to numbers with positive exponents.
2016-03-11 at 21:26

I need to round a real number to 2 decimals.
2018-03-07 at 08:28

Please tell us what error message you got.

Perhaps, you have forgotten to include the unit "math" to your uses clause.
2018-03-07 at 13:24

Positive Negative

In this example RoundTo(123.375,-2) should round to 123.38 but it rounds to 123.38!!

Whats wrong?
2019-03-06 at 18:32

In this example RoundTo(124.375,-2) should round to 124.38 but it rounds to 124,37!!!

Whats wrong?
2019-03-06 at 18:34

You can find Software by Stefan Trost on sttmedia.com. Do you need an individual software solution according to your needs? - sttmedia.com/contact
Show Profile