Himanshu SharmaSoftware engineer
Let’s talk

PHP · Lesson 8 of 54

Integers, floats and maths

Do arithmetic with integers and floats, use intdiv, modulo and powers, round correctly, and handle float precision when working with money.

13 minThe basicsUpdated 22 October 2026

Awaiting technical review. This lesson is readable but not yet listed in search engines.

By the end of this lessonCalculate with integers and floats, round results correctly and avoid float errors with money.

Arithmetic operators

PHP has the arithmetic operators you know from school, plus two more:

Operator Meaning Example Result
+ add 7 + 2 9
- subtract 7 - 2 5
* multiply 7 * 2 14
/ divide 7 / 2 3.5
% remainder (modulo) 7 % 2 1
** power 7 ** 2 49
php
<?php
$price = 24.99;
$quantity = 3;

echo $price * $quantity . "\n";
echo 100 - 37 . "\n";
echo 2 ** 8 . "\n";
echo 17 % 5 . "\n";
result
74.97
63
256
2

The usual order of operations applies: ** first, then *, / and %, then + and -. Use brackets whenever the order is not obvious to a reader: ($price + $shipping) * $quantity.

Division, intdiv and the remainder

/ always gives the exact answer, so it returns a float unless the division comes out even. When you want only the whole-number part, use intdiv(). Together with % it splits a quantity into groups:

php
<?php
$minutes = 135;
$hours = intdiv($minutes, 60);
$rest = $minutes % 60;

echo "$minutes minutes is $hours h $rest min\n";
var_dump(10 / 5);
var_dump(10 / 4);
result
135 minutes is 2 h 15 min
int(2)
float(2.5)

The two var_dump() lines show the rule: 10 / 5 divides exactly, so the result is the integer 2, while 10 / 4 does not, so it is the float 2.5.

Dividing by zero is an error in PHP 8. It throws a DivisionByZeroError that stops the script unless you catch it, so check divisors that come from user input.

php
<?php
$visits = 0;
$sales = 12;
echo $sales / $visits;
result
Fatal error: Uncaught DivisionByZeroError: Division by zero in /path/to/script.php:4
Stack trace:
#0 {main}
  thrown in /path/to/script.php on line 4

Rounding

Three functions round in different ways:

php
<?php
echo round(4.567, 2) . "\n";
echo round(2.5) . "\n";
echo round(-2.5) . "\n";
echo floor(4.9) . "\n";
echo ceil(4.1) . "\n";
echo round(1234.5678, -2) . "\n";
result
4.57
3
-3
4
5
1200

round() goes to the nearest value, and halves go away from zero. The second argument is the number of decimal places, and a negative number rounds to tens, hundreds and so on. floor() always rounds down and ceil() always rounds up, which is what you want for "how many boxes do I need?" questions: ceil(25 / 6) boxes of six hold 25 items.

Formatting numbers for display

Rounding changes the value; formatting only changes how it is shown. number_format() adds a fixed number of decimals and thousands separators:

php
<?php
$revenue = 1234567.891;
echo number_format($revenue) . "\n";
echo number_format($revenue, 2) . "\n";
echo number_format($revenue, 2, ',', '.') . "\n";
echo number_format(89.5, 2) . "\n";
result
1,234,568
1,234,567.89
1.234.567,89
89.50

The third and fourth arguments set the decimal point and thousands separator, for countries that write numbers differently. For the Indian lakh and crore grouping, PHP's intl extension has NumberFormatter with the en_IN locale.

Floats are approximate

Computers store floats in binary, and most decimal fractions, such as 0.1, have no exact binary form. Tiny errors appear:

php
<?php
$sum = 0.1 + 0.2;
var_dump($sum);
var_dump($sum == 0.3);
var_dump(abs($sum - 0.3) < 0.00001);
result
float(0.30000000000000004)
bool(false)
bool(true)

Never compare floats with ==. Compare the difference with a small tolerance, as in the last line, or round both sides first.

For money, the safest habit is to avoid floats altogether: store amounts as whole numbers of the smallest unit (paise or cents) and only divide by 100 when you display them. For heavy financial maths, PHP's BCMath extension calculates with decimal strings at any precision.

php
<?php
$pricePaise = 8950;        // 89.50
$quantity = 3;
$totalPaise = $pricePaise * $quantity;

echo "Total: " . number_format($totalPaise / 100, 2) . "\n";
echo bcadd('0.1', '0.2', 2) . "\n";
result
Total: 268.50
0.30

Useful maths functions

abs() (absolute value), max() and min() (largest and smallest), sqrt() (square root), pi() and random_int() cover most needs:

php
<?php
echo max(12, 89.5, 24.99) . "\n";
echo min([5, 3, 9]) . "\n";
echo abs(-15) . "\n";
echo sqrt(144) . "\n";
result
89.5
3
15
12

random_int($min, $max) returns a cryptographically secure random integer, suitable for codes and tokens. Prefer it to the older rand().

Common mistakes

  • Comparing floats with ==, which fails on tiny rounding errors.
  • Storing money as floats and adding many of them, which lets errors build up.
  • Confusing rounding with formatting: number_format() returns a string for display; do not calculate with it.
  • Dividing by a value that might be zero, which throws an error in PHP 8.

Exercise

A customer buys 7 Resistance Bands at 14.99 each. Shipping is 5 per order, and orders over 100 ship free. Calculate the total in paise (cents) to avoid float errors, and print it with two decimals.

Show one possible answer
php
<?php
$pricePaise = 1499;
$quantity = 7;
$subtotal = $pricePaise * $quantity;          // 10493
$shipping = $subtotal > 10000 ? 0 : 500;
$total = $subtotal + $shipping;

echo "Subtotal: " . number_format($subtotal / 100, 2) . "\n";
echo "Shipping: " . number_format($shipping / 100, 2) . "\n";
echo "Total: " . number_format($total / 100, 2) . "\n";
result
Subtotal: 104.93
Shipping: 0.00
Total: 104.93

The ? : (ternary) operator picks one of two values; it has its own lesson.

Key points

  • The arithmetic operators are + - * / % and ** (power). / returns a float unless the division is exact.
  • intdiv() divides and keeps the whole-number part; % gives the remainder.
  • round(), floor() and ceil() round in different directions; number_format() formats for display.
  • Floats are approximate: 0.1 + 0.2 is not exactly 0.3. Store money as integer paise or cents, or use the BCMath functions.

Check yourself

1. What is 17 % 5?
2. What does round(2.5) return?
3. Why does var_dump(0.1 + 0.2 == 0.3) print bool(false)?
4. What does 2 ** 10 return?