round
Rounds a number to a given number of decimal places using a chosen rounding mode.
round(int|float $num, int $precision = 0, int|RoundingMode $mode = RoundingMode::HalfAwayFromZero): float- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$num | int|float | The value to round. |
$precisionoptional | int= 0 | Number 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. |
$modeoptional | int|RoundingMode= RoundingMode::HalfAwayFromZero | How 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.
See also
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
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.
<?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.
<?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.
<?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