Numbers and Math
PHP handles everyday arithmetic with the operators you know, plus a large library of math functions. This lesson covers the arithmetic operators and their quirks — especially division — rounding, formatting numbers for display, random numbers, and how to handle money without floating-point errors.
Arithmetic operators
<?php $a = 17; $b = 5; echo $a + $b, "\n"; echo $a - $b, "\n"; echo $a * $b, "\n"; echo $a / $b, "\n"; // division echo $a % $b, "\n"; // remainder (modulo) echo $a ** 2, "\n"; // exponentiation echo -$a, "\n";
22 12 85 3.4 2 289 -17
Division
Unlike many languages, / in PHP doesn't throw away the fraction: dividing two integers gives a float unless the result is a whole number. For integer division, use intdiv():
<?php var_dump(10 / 2); var_dump(7 / 2); var_dump(intdiv(7, 2)); var_dump(-7 % 2); // remainder keeps the sign of the left side var_dump(fmod(7.5, 2)); // remainder for floats
int(5) float(3.5) int(3) int(-1) float(1.5)
Dividing by zero throws a DivisionByZeroError, which stops the script unless it's caught (lesson 44):
<?php $items = 10; $boxes = 0; echo $items / $boxes;
Fatal error: Uncaught DivisionByZeroError: Division by zero in main.php:5
Stack trace:
#0 {main}
thrown in main.php on line 5Rounding
<?php echo round(3.14159, 2), "\n"; echo round(2.5), " ", round(3.5), " ", round(-2.5), "\n"; // halves round away from zero echo round(1234.5678, -2), "\n"; // to the nearest hundred echo floor(4.7), " ", ceil(4.2), "\n"; echo round(2.5, 0, PHP_ROUND_HALF_EVEN), "\n"; // banker's rounding
3.14 3 4 -3 1200 4 5 2
PHP's round() rounds halves away from zero by default — the school rule. Pass a mode such as PHP_ROUND_HALF_EVEN (or the newer RoundingMode enum) for other behaviour.
Math functions
<?php echo abs(-7.5), "\n"; echo sqrt(144), "\n"; echo pow(2, 10), "\n"; echo max(3, 9, 4), " ", min([3, 9, 4]), "\n"; echo M_PI, "\n"; echo round(pi() * 2 ** 2, 3), "\n"; echo intdiv(PHP_INT_MAX, 1_000_000_000), "\n"; echo log(M_E), " ", log10(1000), "\n";
7.5 12 1024 9 3 3.1415926535898 12.566 9223372036 1 3
max and min accept either several arguments or one array.
Formatting numbers
number_format rounds a number and adds thousands separators — ideal for display:
<?php $revenue = 1234567.891; echo number_format($revenue), "\n"; echo number_format($revenue, 2), "\n"; echo number_format($revenue, 2, ',', '.'), "\n"; // European style echo number_format(0.5), "\n";
1,234,568 1,234,567.89 1.234.567,89 1
Lesson 18 shows printf/sprintf for more control over layout.
Money: avoid floats
Because floats can't represent most decimal fractions exactly, small errors creep into money calculations:
<?php $total = 0; foreach ([0.10, 0.20, 0.30] as $price) { $total += $price; } var_dump($total); var_dump($total == 0.6);
float(0.6000000000000001) bool(false)
Two reliable approaches:
- Store whole cents as integers and only format them as currency for display.
- Use decimal arithmetic — the
bcmathextension'sBcMath\Numberclass (PHP 8.4+) does exact decimal maths with normal operators.
<?php $cents = 0; foreach ([10, 20, 30] as $priceInCents) { $cents += $priceInCents; } printf("Total: %d.%02d\n", intdiv($cents, 100), $cents % 100); $a = new BcMath\Number('0.10'); $sum = $a + '0.20' + '0.30'; echo "Exact: $sum\n"; var_dump($sum == new BcMath\Number('0.6'));
Total: 0.60 Exact: 0.60 bool(true)
Random numbers
random_int($min, $max) returns a random integer between the limits, inclusive. It uses a cryptographically secure source, so it's safe for things like generating codes:
<?php $dice = random_int(1, 6); echo $dice >= 1 && $dice <= 6 ? "Rolled a valid die\n" : "Bug!\n"; $rng = new Random\Randomizer(new Random\Engine\Mt19937(42)); // seeded: repeatable echo $rng->getInt(1, 100), " ", $rng->getInt(1, 100), "\n"; echo $rng->shuffleArray(['a', 'b', 'c', 'd']) == ['a', 'b', 'c', 'd'] ? "same order\n" : "shuffled\n";
Rolled a valid die 43 68 shuffled
The Random\Randomizer class (PHP 8.2+) offers shuffling, picking array keys and random strings. With a seeded engine it produces the same sequence every run — useful for tests and simulations.
Try it yourself
Split a restaurant bill between friends, working in cents to avoid rounding errors.
Total with tip: 100.51 Each pays 33.50, plus 1 cent(s) left over