## Introduction

Rounding is an extremely mainstream operation when it comes to numbers in any programming language.

Needless to say, rounding is a concern typically associated with floating-point numbers, not with integers. *Who wants to round integers anyways?*

In this chapter, we aim to explore all the different ways to round floating-point numbers in PHP, particularly using the `round()`

function with its different modes and the functions `floor()`

and `ceil()`

.

We'll also see how to use `round()`

to round a number to given decimal places, and in some cases, to given significant figures.

## The `round()`

function

PHP provides a goto function to round floating-point numbers to a given precision.

Here's how it looks:

**round**(*$number*, *$precision* = 0, *$mode* = PHP_ROUND_HALF_UP)

The first * $number* argument is the number to round, while the second

*argument is the precision. This second argument is optional and defaults to*

`$precision`

`0`

. That is, the number is rounded to the nearest unit.We'll explore the last * $mode* argument later below.

* $precision* can be a positive integer or a negative integer. Here's how

*works on a given number*

`$precision`

`1780.5389`

.If * $precision* is

`0`

, the number is rounded to the nearest units as shown in the figure.If it's positive, the corresponding position to the right is determined and the number rounded to that very position.

For instance, * $precision* of

`1`

would round `1780.`**5**389

to `1780.5`

while a *of*

`$precision`

`2`

would round `1780.5`**3**89

to `1780.54`

. And so on and so forth.What would `round(1780.5389, 3)`

return?

`1780.54`

`1780.538`

`1780.539`

`round(1780.5389, 3)`

rounds `1780.53`**8**9

to the nearest thousandth place (as highlighted) to give the number `1780.539`

. This goes with choice (C).Similarly, a negative value of * $precision* would shift this position leftwards.

For instance, a * $precision* of

`-1`

would round `17`**8**0.5389

to `1780`

; while a *of*

`$precision`

`-2`

would round `1`**7**80.5389

to `1800`

.What would `round(1780.5389, -3)`

return?

`1780.0`

`1800.0`

`2000.0`

`round(1780.5389, -3)`

rounds **1**780.5389

to the nearest thousands (as highlighted) to give the number `2000.0`

. This goes with choice (C).*Simple.*

Let's use the `round()`

function on the same number `1780.5389`

with different precisions:

```
<?php
$num = 1780.5389;
echo 'Precision of 5: ', round($num, 5), "\n";
echo 'Precision of 4: ', round($num, 4), "\n";
echo 'Precision of 3: ', round($num, 3), "\n";
echo 'Precision of 2: ', round($num, 2), "\n";
echo 'Precision of 1: ', round($num, 1), "\n";
echo 'Precision of 0: ', round($num, 0), "\n";
echo 'Precision of -1: ', round($num, -1), "\n";
echo 'Precision of -2: ', round($num, -2), "\n";
echo 'Precision of -3: ', round($num, -3), "\n";
echo 'Precision of -4: ', round($num, -4), "\n";
echo 'Precision of -5: ', round($num, -5), "\n";
```

Notice that beyond a precision of `4`

here, there is no difference between the rounded numbers. This is because rounding can only happen upto a precision that's equal to or less than the precision of the given number. In the case above, `1780.5389`

is to a precision of 4 decimal places and therefore we can't go more precise than that.

Moreover, when the precision is negative and causes the number to be rounded to a position that's not in the number, `0`

is returned. This is what happens in `round(1780.5389, -4)`

. The very first position in `1780.5389`

is represented by a * $precision* value of

`-3`

— going less than this value is not possible.Apart from * $precision*, another useful argument of the

`round()`

function is the third **argument.**

`$mode`

**argument serves to specify the exact**

`$mode`

**rounding behavior**to use on the digit pointed by the

*argument when the sequence of digits after it form a*

`$precision`

**half value**.

For instance, it would be applied on the numbers

`1.3`**5**

(in `round(1.35, 1)`

), `1.`**5**

(in `round(1.5)`

), `27`**50**

(in `round(2750, -2)`

), where the sequence of digits highlighted after the desired position form a perfect half. However, it would NOT be applied on the numbers `1.3`**52**

, `1.`**5005**

, `27`**51**

.The four possible modes are given by the following four constants.

Mode | Purpose |
---|---|

`PHP_ROUND_HALF_UP` | Round the previous digit to the next digit. |

`PHP_ROUND_HALF_DOWN` | Round the previous digit to the previous digit. |

`PHP_ROUND_HALF_EVEN` | Round the previous digit to the next or previous digit, whichever is even. |

`PHP_ROUND_HALF_ODD` | Round the previous digit to the next or previous digit, whichever is odd. |

* $mode* is an optional parameter which, if omitted, defaults to

`PHP_ROUND_HALF_UP`

.Let's consider a couple of examples.

In the code below, we round the number `1.35`

to 1 decimal place (since that's when the next digit `5`

would be considered in the rounding phase) in all the aforementioned modes:

```
<?php
$num = 1.35;
echo 'Round up: ', round($num, 1, PHP_ROUND_HALF_UP), "\n";
echo 'Round down: ', round($num, 1, PHP_ROUND_HALF_DOWN), "\n";
echo 'Round to even: ', round($num, 1, PHP_ROUND_HALF_EVEN), "\n";
echo 'Round to odd: ', round($num, 1, PHP_ROUND_HALF_ODD), "\n";
```

Similarly, below we round the number `2650`

to the nearest hundreds (since that's when the next digit `5`

would be considered in the rounding phase) in all the modes:

```
<?php
$num = 2650;
echo 'Round up: ', round($num, -2, PHP_ROUND_HALF_UP), "\n";
echo 'Round down: ', round($num, -2, PHP_ROUND_HALF_DOWN), "\n";
echo 'Round to even: ', round($num, -2, PHP_ROUND_HALF_EVEN), "\n";
echo 'Round to odd: ', round($num, -2, PHP_ROUND_HALF_ODD), "\n";
```

Note that, as stated before, if the sequence of digits after the digit given by * $precision* is not a perfect half, the mode won't matter.

This can be seen as follows. The code is the same as before except for adding changing the number from `2650`

to `2651`

:

```
<?php
$num = 2651;
echo 'Round up: ', round($num, -2, PHP_ROUND_HALF_UP), "\n";
echo 'Round down: ', round($num, -2, PHP_ROUND_HALF_DOWN), "\n";
echo 'Round to even: ', round($num, -2, PHP_ROUND_HALF_EVEN), "\n";
echo 'Round to odd: ', round($num, -2, PHP_ROUND_HALF_ODD), "\n";
```

As we know, `51`

is not a perfect half and hence when PHP tries to round the digit `6`

(as given by the * $precision* argument

`-2`

), it is rounded upwards to `7`

to finally give the number `2700`

(since `51`

is above the half mark).## Floor and ceil

As you start to learn to implement various algorithms and data structures in PHP, you'll start to see the applications of two very common ideas from number theory — ** floor** and

**.**

*ceil*Both of these are essentially mathematical functions that round a given number to a particular integer. Let's see what both of them exactly do.

**floor function**rounds a given number to the

**largest integer less than or equal to the number**. It's denoted as ::\lfloor x \rfloor::, where ::x:: is the number to floor.

For instance, ::\lfloor -10 \rfloor:: gives ::-10::, ::\lfloor -3.2 \rfloor:: gives ::-4::, ::\lfloor 5.02 \rfloor:: gives ::5::, ::\lfloor 15.99 \rfloor:: gives ::15::, ::\lfloor 10 \rfloor:: gives ::10::, and so on.

In contrary to this:

**ceil function**rounds a given number to the

**smallest integer greater than or equal to the number**. It's denoted as ::\lceil x \rceil::, where ::x:: denotes the number to ceil.

For instance, ::\lceil -10 \rceil:: gives ::-10::, ::\lceil -3.2 \rceil:: gives ::-3::, ::\lceil 5.02 \rceil:: gives ::6::, ::\lceil 15.99 \rceil:: gives ::16::, ::\lceil 10 \rceil:: gives ::10::, and so on.

In PHP, the functions ** floor()** and

**allow us to perform these very mathematical operations on given numbers.**

`ceil()`

Consider the code below where we use the `floor()`

function on the same values as shown above:

```
<?php
echo floor(-10), "\n";
echo floor(-3.2), "\n";
echo floor(5.02), "\n";
echo floor(15.99), "\n";
echo floor(10), "\n";
```

Now, time for the `ceil()`

function:

```
<?php
echo ceil(-10), "\n";
echo ceil(-3.2), "\n";
echo ceil(5.02), "\n";
echo ceil(15.99), "\n";
echo ceil(10), "\n";
```

*Easy, wasn't this?*

`floor()`

and `ceil()`

in PHP return floats!

Note that contrary to what one might expect, the `floor()`

and `ceil()`

functions both **return back a float**, NOT an integer!

```
<?php
var_dump(floor(10.5));
var_dump(ceil(10.5));
```

This is extremely important to keep in mind.

Many languages provide similar `floor()`

and `ceil()`

functions but they return back integers. PHP, however, takes a different approach here.

*But why?*

Well, as per the official documentation, this is done to enable representing values that otherwise couldn't be represented in the native `int`

type.

This approach only benefits 32-bit machines. On 32-bit machines, the maximum integer possible in the native `int`

type is `2147483647`

. However, the maximum integer possible in the `float`

type is `9007199254740991`

.

64-bit machines, on the other hand, don't really benefit from this approach. This is because the maximum value of the `int`

type on a 64-bit machine is larger than the maximum integer capable to be represented in the `float`

format.

However, this isn't a bad approach even from the perspective of a 64-bit machine.

This is because floats larger than the maximum `int`

value can't really be precise integers and hence, in any way, there would be no advantage of making the return type of `floor()`

or `ceil()`

an integer.