Arithmetic Operators
What Are Arithmetic Operators? In simple terms: Arithmetic operators perform basic mathematics: addition, subtraction, multiplication, division, remainder, and powers. Technically: Arithmetic operator
What Are Arithmetic Operators?
In simple terms: Arithmetic operators perform basic mathematics: addition, subtraction, multiplication, division, remainder, and powers.
Technically: Arithmetic operators take numeric operands (int or float) and return a numeric result. When an operand is not a number — such as a numeric string, a boolean, or null — PHP converts it to a number first (see PHP Type Juggling).
Why They Matter
Arithmetic is everywhere in applications: cart totals, taxes, discounts, averages, time conversions, pagination, and scores. The operators are simple, but their result types and edge cases (division, remainders, negative numbers, zero) are where bugs appear.
The Arithmetic Operators
| Operator | Name | Example | Result |
|---|---|---|---|
+$a | Identity | +"42" | 42 (converted to a number) |
-$a | Negation | -17 | -17 |
$a + $b | Addition | 17 + 5 | 22 |
$a - $b | Subtraction | 17 - 5 | 12 |
$a * $b | Multiplication | 17 * 5 | 85 |
$a / $b | Division | 17 / 5 | 3.4 |
$a % $b | Modulo (remainder) | 17 % 5 | 2 |
$a ** $b | Exponentiation | 17 ** 2 | 289 |
Example
<?php
$a = 17;
$b = 5;
var_dump($a + $b);
var_dump($a - $b);
var_dump($a * $b);
var_dump($a / $b);
var_dump($a % $b);
var_dump($a ** 2);
var_dump(-$a);
Output
int(22)
int(12)
int(85)
float(3.4)
int(2)
int(289)
int(-17)
How It Works
- Addition, subtraction, multiplication, and exponentiation of integers produce integers (unless the result exceeds
PHP_INT_MAX, in which case it becomes a float). - Division produced a float because 17 is not evenly divisible by 5.
- Modulo returns the remainder:
17 = 3 × 5 + 2.
Result Types
The type of the result depends on the operands and the operator:
| Operation | Result Type |
|---|---|
int + int, int - int, int * int | int (or float on overflow) |
Any operation involving a float | float |
int / int, divides evenly | int — 10 / 2 is int(5) |
int / int, does not divide evenly | float — 10 / 4 is float(2.5) |
int % int | int (operands are converted to integers) |
int ** int, non-negative exponent | int (or float on overflow) |
int ** negative int | float — 2 ** -1 is float(0.5) |
<?php
var_dump(10 / 2);
var_dump(10 / 4);
var_dump(2 * 1.5);
var_dump(3.0 + 2);
Output
int(5)
float(2.5)
float(3)
float(5)
A float operand makes the result a float even when the value is whole (float(3)). This matters with strict type declarations: passing 3.0 to an int parameter in strict mode is a TypeError.
Division
Normal Division: /
/ returns the exact quotient, as an int if the division is exact and a float otherwise.
Integer Division: intdiv()
PHP has no integer division operator. Use intdiv(), which discards the fractional part (truncating toward zero):
<?php
var_dump(intdiv(17, 5));
var_dump(intdiv(-17, 5));
var_dump((int) (17 / 5));
Output
int(3)
int(-3)
int(3)
intdiv() is clearer than (int) ($a / $b) and avoids converting through a float, which can lose precision for very large integers.
Division by Zero
<?php
$visits = 0;
$sales = 12;
try {
$conversionRate = $sales / $visits;
} catch (DivisionByZeroError $e) {
echo "Cannot calculate: " . $e->getMessage() . "\n";
}
$conversionRate = $visits > 0 ? $sales / $visits * 100 : 0;
echo "Conversion rate: $conversionRate%\n";
Output
Cannot calculate: Division by zero
Conversion rate: 0%
Since PHP 8.0, dividing by zero with /, %, or intdiv() throws a DivisionByZeroError. The second calculation shows the better approach: check the divisor before dividing and decide what the result should be when it is zero.
Modulo: %
What It Does
$a % $b returns the remainder after dividing $a by $b.
<?php
var_dump(10 % 3);
var_dump(12 % 4);
var_dump(-10 % 3);
var_dump(10 % -3);
var_dump(7.9 % 3);
Output
int(1)
int(0)
int(-1)
int(1)
PHP Deprecated: Implicit conversion from float 7.9 to int loses precision in /path/script.php on line 6
int(1)
Rules
- The result has the same sign as the left operand:
-10 % 3is-1, while10 % -3is1. - Operands are converted to integers.
7.9 % 3is calculated as7 % 3, and since PHP 8.1 the lost fraction triggers a deprecation notice. Usefmod(7.9, 3)for floating-point remainders. % 0throwsDivisionByZeroError.
Common Uses
<?php
$rows = ['Asha', 'Bala', 'Charu', 'Dev'];
foreach ($rows as $index => $name) {
$style = $index % 2 === 0 ? 'even' : 'odd';
echo "$name ($style)\n";
}
$totalMinutes = 135;
echo intdiv($totalMinutes, 60) . " h " . $totalMinutes % 60 . " min\n";
$hour = 22;
echo "In 5 hours it will be " . ($hour + 5) % 24 . ":00\n";
Output
Asha (even)
Bala (odd)
Charu (even)
Dev (odd)
2 h 15 min
In 5 hours it will be 3:00
| Use | Pattern |
|---|---|
| Even or odd | $n % 2 === 0 |
| Alternating styles | $index % 2 |
| Splitting units | intdiv($minutes, 60) hours and $minutes % 60 minutes |
| Wrapping around a range | ($hour + 5) % 24 |
| Doing something every N items | $i % 100 === 0 |
Exponentiation: **
<?php
var_dump(2 ** 8);
var_dump(10 ** -2);
var_dump(16 ** 0.5);
var_dump(-2 ** 2);
var_dump((-2) ** 2);
Output
int(256)
float(0.01)
float(4)
int(-4)
int(4)
The Negative Base Trap
-2 ** 2 is -4, not 4. The ** operator has higher precedence than unary minus, so PHP calculates -(2 ** 2). Write (-2) ** 2 when the base itself is negative. This matches the usual convention in mathematics.
** is also right-associative: 2 ** 3 ** 2 is 2 ** 9 (512). pow($base, $exp) is the function equivalent of **.
Unary Plus and Minus
<?php
$input = "42";
$price = "3.50";
var_dump(+$input);
var_dump(+$price);
var_dump(-$input);
Output
int(42)
float(3.5)
int(-42)
Unary + converts a numeric string to int or float without changing its value. It works, but (int) or (float) casts are clearer about the intended type, and validation with filter_var() is safer for user input.
Arithmetic With Non-Numbers
| Operand | Treated As | Example | Result |
|---|---|---|---|
Numeric string "10" | 10 | "10" + 5 | 15 |
Leading-numeric string "10 kg" | 10, with a warning | "10 kg" + 5 | 15 + Warning |
Non-numeric string "abc" | — | "abc" + 5 | TypeError |
true / false | 1 / 0 | true + 5 | 6 |
null | 0 | null + 5 | 5 |
| Array | — | [1] * 2 | TypeError |
Arrays support only + (array union), which has nothing to do with numeric addition. All other arithmetic operators throw a TypeError for arrays.
Practical Example: Shopping Cart Totals
<?php
$cart = [
['name' => 'Notebook', 'price' => 60, 'qty' => 4],
['name' => 'Gel Pen', 'price' => 25, 'qty' => 6],
['name' => 'Backpack', 'price' => 1299, 'qty' => 1],
];
$discountPercent = 10;
$gstPercent = 18;
$subtotal = 0;
foreach ($cart as $item) {
$subtotal = $subtotal + $item['price'] * $item['qty'];
}
$discount = $subtotal * $discountPercent / 100;
$afterDiscount = $subtotal - $discount;
$gst = $afterDiscount * $gstPercent / 100;
$total = $afterDiscount + $gst;
printf("Subtotal: ₹%9.2f\n", $subtotal);
printf("Discount: -₹%9.2f\n", $discount);
printf("GST 18%%: ₹%9.2f\n", $gst);
printf("Total: ₹%9.2f\n", $total);
Output
Subtotal: ₹ 1689.00
Discount: -₹ 168.90
GST 18%: ₹ 273.62
Total: ₹ 1793.72
Step-by-Step Explanation
- Each line total is
price × qty. Because*has higher precedence than+,$subtotal + $item['price'] * $item['qty']multiplies first, then adds. The subtotal is240 + 150 + 1299 = 1689. - The discount is 10% of the subtotal:
1689 × 10 / 100 = 168.9. - GST is calculated on the discounted amount:
1520.1 × 18 / 100 = 273.618, displayed as273.62after rounding to two decimals. - The total is
1520.1 + 273.618 = 1793.718, displayed as1793.72. printf()with%9.2faligns the amounts and shows two decimal places.%%prints a literal percent sign.
Notice that the displayed GST is rounded, but the total is calculated from the unrounded GST. On a real invoice, each displayed amount must add up exactly, so tax is usually rounded to the paisa before it is added, and calculations are done in integer paise (see PHP Floats).
Practical Example: Splitting a Bill Fairly
Dividing money evenly often leaves a remainder. Integer arithmetic handles it exactly.
<?php
function splitAmount(int $totalPaise, int $people): array
{
$base = intdiv($totalPaise, $people);
$remainder = $totalPaise % $people;
$shares = [];
for ($i = 0; $i < $people; $i++) {
$shares[] = $base + ($i < $remainder ? 1 : 0);
}
return $shares;
}
$shares = splitAmount(100000, 3); // ₹1,000.00 among 3 people
foreach ($shares as $index => $paise) {
printf("Person %d pays ₹%.2f\n", $index + 1, $paise / 100);
}
printf("Total collected: ₹%.2f\n", array_sum($shares) / 100);
Output
Person 1 pays ₹333.34
Person 2 pays ₹333.33
Person 3 pays ₹333.33
Total collected: ₹1000.00
How It Works
- Working in paise (
100000) keeps every value an integer. intdiv(100000, 3)gives33333paise each, and100000 % 3leaves1paisa.- The first
$remainderpeople pay one extra paisa, so the shares always add up to exactly the total. Dividing a float (1000 / 3 = 333.333...) and rounding each share would collect ₹999.99 instead.
Common Mistakes
Expecting / to Return an Integer
Effect: 7 / 2 is 3.5, which may break array indexes or int parameters.
Fix: Use intdiv(), or round explicitly with round(), floor(), or ceil().
Using % With Decimals
Effect: The fractional part is dropped (with a deprecation notice).
Fix: Use fmod().
Forgetting the Sign Rule of %
Effect: -7 % 3 is -1, so $n % 2 === 1 fails for negative odd numbers.
Fix: Test even numbers with $n % 2 === 0, or use abs($n) % 2.
Writing -2 ** 2 for a Negative Base
Effect: The result is -4.
Fix: (-2) ** 2.
Dividing by Values That Can Be Zero
Effect: DivisionByZeroError.
Fix: Check the divisor first.
Doing Arithmetic on Formatted Strings
Effect: "1,299" + 1 uses only 1 (with a warning) because of the comma.
Fix: Keep numbers as numbers; format only for display.
Best Practices
- Keep calculations on real numbers (
int,float), and convert input before calculating. - Use parentheses whenever the order of operations is not obvious.
- Use
intdiv()and%together for splitting units (hours/minutes, pages, shares). - Guard every division and modulo against zero.
- Use integer arithmetic in the smallest unit for money.
- Round only for display, at the end of the calculation.
Official reference: https://www.php.net/manual/en/language.operators.arithmetic.php