round

Rounds a number to a given number of decimal places using a chosen rounding mode.

Signature
round(int|float $num, int $precision = 0, int|RoundingMode $mode = RoundingMode::HalfAwayFromZero): float
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$numint|floatThe value to round.
$precisionoptionalint= 0Number of decimal digits to round to. Positive values round after the decimal point; negative values round before it, so -2 rounds to the nearest hundred.
$modeoptionalint|RoundingMode= RoundingMode::HalfAwayFromZeroHow to resolve values that fall exactly halfway, or which direction to always round. Accepts a RoundingMode enum case or one of the PHP_ROUND_HALF_* constants.

Return value

floatThe value of num rounded to precision decimal places, always as a float.

Errors

As of PHP 8.4.0, throws a ValueError if $mode is not a valid rounding mode. Earlier versions silently used PHP_ROUND_HALF_UP.

Changelog

  • PHP 8.4.0The RoundingMode enum was introduced, adding TowardsZero, AwayFromZero, NegativeInfinity and PositiveInfinity. An invalid $mode now throws a ValueError instead of silently falling back to PHP_ROUND_HALF_UP.
  • PHP 8.0.0$num no longer accepts internal objects that support numeric conversion.

round() always returns a float, even when you round to zero decimals and even when the input was an int. If you need a real integer, cast it: (int) round($n).

Choosing a mode

The default, RoundingMode::HalfAwayFromZero (the old PHP_ROUND_HALF_UP), sends 2.5 to 3 and -2.5 to -3. Accounting and statistics often want RoundingMode::HalfEven — banker's rounding — which sends 2.5 to 2 and 3.5 to 4, so repeated rounding does not drift upward. PHP 8.4 added four non-half modes that ignore the midpoint question entirely: TowardsZero, AwayFromZero, NegativeInfinity and PositiveInfinity. Those last two behave like floor() and ceil() but respect $precision.

Negative precision

A negative $precision rounds to the left of the decimal point: round(1234, -2) gives 1200.0. Handy for bucketing values into tens, hundreds or thousands.

Rounding is not formatting

round(1.10, 2) returns the float 1.1, and echoing it prints 1.1, not 1.10. For a fixed number of visible decimals use number_format() or sprintf('%.2f', ...). And never store money as a rounded float — keep integer cents or use the bcmath extension.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Trim a computed price or tax total to two decimal places before display
  • Bucket a value to the nearest hundred with a negative precision for a histogram
  • Apply banker's rounding to an accounting figure so repeated rounding does not bias upward
  • Round a percentage to one decimal for a report

Frequently asked questions

Why does round() return a float instead of an int?

round() is documented to return float in every case, including round(3.5) which gives float(4). Cast the result with (int) if you need a true integer, but be aware that very large floats cannot be represented exactly as ints.

How do I round to 2 decimal places and keep the trailing zero?

round() returns a number, so 19.10 becomes 19.1 when echoed. Use number_format($value, 2) or sprintf('%.2f', $value) to produce a string with exactly two decimals.

What is the difference between round(), ceil() and floor()?

round() goes to the nearest value using the chosen mode, ceil() always goes up and floor() always goes down. Unlike round(), ceil() and floor() take no precision argument - use round() with RoundingMode::PositiveInfinity or NegativeInfinity if you need directional rounding at a decimal place.

More examples

Comparing every rounding mode

Only the half-* modes disagree at the midpoint: HalfEven sends 2.5 down to 2 but 3.5 up to 4, while HalfOdd does the opposite. TowardsZero and AwayFromZero ignore the midpoint rule and always truncate or always expand.

Example · php
<?php
$modes = [
    'HalfAwayFromZero' => RoundingMode::HalfAwayFromZero,
    'HalfTowardsZero'  => RoundingMode::HalfTowardsZero,
    'HalfEven'         => RoundingMode::HalfEven,
    'HalfOdd'          => RoundingMode::HalfOdd,
    'TowardsZero'      => RoundingMode::TowardsZero,
    'AwayFromZero'     => RoundingMode::AwayFromZero,
];
foreach ($modes as $name => $mode) {
    printf("%-17s 2.5 -> %-4s 3.5 -> %s\n",
        $name, round(2.5, 0, $mode), round(3.5, 0, $mode));
}

Rounding is not the same as formatting

round() produces a numeric value, so trailing zeros disappear when you echo it. number_format() and sprintf() are what give you a fixed two-decimal string, and an explicit cast is what gives you an int.

Example · php
<?php
$price = round(19.10, 2);
var_dump($price);                    // float(19.1)
echo $price, "\n";                   // 19.1
echo number_format($price, 2), "\n"; // 19.10
echo sprintf('%.2f', $price), "\n";  // 19.10

var_dump(round(7.0));                // float(7) - still a float
var_dump((int) round(7.4));          // int(7)

Negative precision for bucketing

A negative precision rounds to the left of the decimal point. Each response time collapses to the nearest hundred milliseconds, which is a quick way to group raw measurements into histogram buckets.

Example · php
<?php
$responseTimes = [143, 287, 651, 1042, 88];
foreach ($responseTimes as $ms) {
    echo $ms, ' ms -> bucket ', round($ms, -2), "\n";
}

echo round(1449, -3), "\n";  // 1000
echo round(1550, -3), "\n";  // 2000

Discussion

  • Be the first to comment on this lesson.