PHP Math
PHP includes a set of built-in mathematical functions and constants for everyday calculations — absolute values, minimums and maximums, powers and roots, rounding, logarithms, trigonometry, and base c
PHP includes a set of built-in mathematical functions and constants for everyday calculations — absolute values, minimums and maximums, powers and roots, rounding, logarithms, trigonometry, and base conversion. They are part of the PHP core, so no extension needs to be installed.
This lesson explains the most useful functions, shows how they behave with different inputs, and applies them to real calculations: discounts, percentage changes, compound interest, loan EMIs, distances, and statistics.
Related lessons: Integer behavior (division, modulo, overflow) is covered in PHP Numbers; float precision and rounding modes in PHP Floats; secure random numbers in PHP Random Numbers.
Overview of Common Math Functions
| Function | Purpose | Example | Result |
|---|---|---|---|
abs($n) | Absolute value (distance from zero) | abs(-7.5) | 7.5 |
max(...) / min(...) | Largest / smallest value | max(3, 9, 2) | 9 |
round($n, $p) | Round to precision | round(3.456, 2) | 3.46 |
floor($n) / ceil($n) | Round down / up | ceil(4.1) | 5 |
intdiv($a, $b) | Integer division | intdiv(17, 5) | 3 |
fmod($a, $b) | Float remainder | fmod(7.5, 2) | 1.5 |
sqrt($n) | Square root | sqrt(144) | 12 |
pow($b, $e) / ** | Power | 2 ** 10 | 1024 |
exp($n) | e raised to a power | exp(1) | 2.718281828459 |
log($n, $base) | Logarithm (natural by default) | log(8, 2) | 3 |
log10($n) | Base-10 logarithm | log10(1000) | 3 |
hypot($x, $y) | Length of the hypotenuse | hypot(3, 4) | 5 |
pi() / M_PI | π | M_PI | 3.1415926535898 |
deg2rad() / rad2deg() | Convert angles | deg2rad(180) | 3.1415926535898 |
sin(), cos(), tan() … | Trigonometry (radians) | sin(deg2rad(30)) | 0.5 |
array_sum() / array_product() | Sum / product of an array | array_sum([1, 2, 3]) | 6 |
base_convert() | Convert between bases 2–36 | base_convert("ff", 16, 2) | "11111111" |
The "Result" column shows the values as echo prints them. Many of these functions return floats even when the result looks whole, as explained below.
Absolute Value: abs()
abs() returns the distance of a number from zero — always non-negative.
<?php
echo abs(-15) . "\n";
echo abs(15) . "\n";
echo abs(-7.5) . "\n";
$budget = 5000;
$spent = 6250;
$difference = $budget - $spent;
echo "Over budget by ₹" . abs($difference) . "\n";
Output
15
15
7.5
Over budget by ₹1250
abs() keeps the type of its argument: an int stays an int, a float stays a float. It is typically used when the size of a difference matters but not its direction — temperature changes, distances between values, or tolerance checks such as abs($a - $b) < 0.001.
Minimum and Maximum: min() and max()
Syntax
max(mixed $value, mixed ...$values): mixed
max(array $values): mixed
Both functions accept either several arguments or a single array.
Example
<?php
echo max(4, 12, 7) . "\n";
echo min(4, 12, 7) . "\n";
$prices = [1299, 499, 2499, 899];
echo "Highest: " . max($prices) . "\n";
echo "Lowest: " . min($prices) . "\n";
Output
12
4
Highest: 2499
Lowest: 499
Clamping a Value Into a Range
Combining min() and max() keeps a value within limits — one of the most common uses in real code:
<?php
function clamp(int|float $value, int|float $minimum, int|float $maximum): int|float
{
return max($minimum, min($maximum, $value));
}
echo clamp(150, 1, 100) . "\n";
echo clamp(-5, 1, 100) . "\n";
echo clamp(42, 1, 100) . "\n";
Output
100
1
42
min($maximum, $value) caps the value at the maximum; max($minimum, ...) raises it to at least the minimum. Typical uses: page numbers, quantities, volume levels, percentages, and items-per-page settings from user input.
Things to Know
- Empty arrays throw an error.
max([])throws aValueErrorin PHP 8 ("must contain at least one element"). Check$array !== []first. - Mixed types are compared with PHP's standard comparison rules, which can be surprising (for example, numeric strings compare as numbers, other strings alphabetically). Keep the values to a single type.
Powers and Roots
Example
<?php
echo 2 ** 10 . "\n";
echo pow(5, 3) . "\n";
echo 9 ** 0.5 . "\n";
echo sqrt(144) . "\n";
echo 27 ** (1 / 3) . "\n";
var_dump(sqrt(144));
var_dump(2 ** 10);
Output
1024
125
3
12
3
float(12)
int(1024)
How It Works
**is the exponentiation operator;pow()is the equivalent function.- An integer base with a non-negative integer exponent returns an
int(unless it overflows). Fractional exponents produce floats. - A fractional exponent calculates roots:
** 0.5is the square root,** (1/3)the cube root. sqrt()always returns a float, even for perfect squares —var_dump(sqrt(144))showsfloat(12).sqrt()of a negative number returnsNAN.
Note:
**is right-associative:2 ** 3 ** 2means2 ** (3 ** 2)=2 ** 9=512, not(2 ** 3) ** 2=64. Use parentheses to make the order clear.
Logarithms and Exponentials
<?php
echo log(M_E) . "\n"; // natural logarithm (base e)
echo log10(1000) . "\n"; // base 10
echo log(8, 2) . "\n"; // base 2
echo exp(1) . "\n"; // e¹
echo log(1) . "\n";
Output
1
3
3
2.718281828459
0
log($n)with one argument is the natural logarithm (base e). The second argument sets another base.exp($n)is e raised to the power$n; it is the inverse oflog().log(0)returns-INF, and the logarithm of a negative number returnsNAN.
Logarithms are used for growth calculations ("how many years until an investment doubles?"), scaling values for charts, and measuring orders of magnitude.
Trigonometry and Angles
PHP's trigonometric functions use radians, not degrees. Convert with deg2rad() and rad2deg().
<?php
echo M_PI . "\n";
echo rad2deg(M_PI) . "\n";
echo sin(deg2rad(30)) . "\n";
echo cos(deg2rad(60)) . "\n";
var_dump(sin(deg2rad(30)));
Output
3.1415926535898
180
0.5
0.5
float(0.49999999999999994)
echo prints 0.5, but var_dump() reveals the actual stored value 0.49999999999999994. This is normal floating-point behavior: π cannot be stored exactly, so trigonometric results are approximations. Round results for display, and compare with a tolerance (see PHP Floats).
Available functions include sin(), cos(), tan(), asin(), acos(), atan(), atan2(), and hyperbolic versions such as sinh().
Useful Math Constants
| Constant | Value | Meaning |
|---|---|---|
M_PI | 3.14159… | π |
M_E | 2.71828… | Euler's number e |
M_SQRT2 | 1.41421… | √2 |
M_PI_2 | 1.57079… | π/2 |
M_LN2 | 0.69314… | Natural log of 2 |
Remainders With Floats: fmod()
The % operator works with integers only. For decimal values, use fmod():
<?php
var_dump(fmod(7.5, 2));
var_dump(fmod(10, 3));
var_dump(fmod(-7.5, 2));
Output
float(1.5)
float(1)
float(-1.5)
Like %, the sign of the result follows the first argument. A common use is wrapping angles or time values, such as fmod($degrees, 360).
Sums and Products of Arrays
<?php
$cart = [19.5, 250, 80.25];
$dimensions = [2, 3, 4];
echo array_sum($cart) . "\n";
echo array_product($dimensions) . "\n";
echo array_sum([]) . "\n";
Output
349.75
24
0
array_sum()adds all values; an empty array returns0.array_product()multiplies all values; an empty array returns1.- Both work on the array values. Non-numeric values are not silently ignored in recent PHP versions: since PHP 8.3, unsupported values (such as arrays or objects) produce a warning.
To sum one field from a list of records, combine with array_column():
<?php
$items = [
['name' => 'Pen', 'price' => 15, 'qty' => 10],
['name' => 'Notebook', 'price' => 60, 'qty' => 3],
];
echo array_sum(array_column($items, 'qty')) . " items\n";
Output
13 items
Base Conversion
| Function | Converts |
|---|---|
decbin(), dechex(), decoct() | Decimal → binary / hexadecimal / octal string |
bindec(), hexdec(), octdec() | Binary / hexadecimal / octal string → number |
base_convert($str, $from, $to) | Any base 2–36 → any base 2–36 |
<?php
echo dechex(255) . "\n";
echo hexdec("ff") . "\n";
echo base_convert("ff", 16, 2) . "\n";
echo base_convert("255", 10, 36) . "\n";
Output
ff
255
11111111
73
Base 36 uses the digits 0–9 and letters a–z, which produces short identifiers: 255 is 7 × 36 + 3, written 73. URL shorteners use similar encodings to turn numeric IDs into compact codes.
Note:
base_convert()works with floats internally and loses precision for very large numbers. Use GMP (gmp_strval(gmp_init($str, $from), $to)) for large values.
Practical Calculations
Discounts and Percentages
<?php
$price = 999;
$discountPercent = 15;
$discount = $price * $discountPercent / 100;
$finalPrice = $price - $discount;
printf("Discount: ₹%.2f\n", $discount);
printf("Final price: ₹%.2f\n", $finalPrice);
$oldVisitors = 1200;
$newVisitors = 1500;
$change = ($newVisitors - $oldVisitors) / $oldVisitors * 100;
printf("Visitor change: %+.1f%%\n", $change);
Output
Discount: ₹149.85
Final price: ₹849.15
Visitor change: +25.0%
- Percentage of a value:
value × percent / 100. - Percentage change:
(new − old) / old × 100. The%+format shows the sign, so a decrease would display as-12.5%. - Guard against division by zero when the old value can be
0.
Compound Interest
<?php
$principal = 100000;
$annualRate = 0.08;
$years = 5;
$amount = $principal * (1 + $annualRate) ** $years;
echo "Amount after $years years: ₹" . number_format($amount, 2) . "\n";
echo "Interest earned: ₹" . number_format($amount - $principal, 2) . "\n";
Output
Amount after 5 years: ₹146,932.81
Interest earned: ₹46,932.81
The formula is A = P × (1 + r)^n, where P is the principal, r the annual rate, and n the number of years. ** performs the power.
Loan EMI (Equated Monthly Installment)
<?php
function monthlyEmi(float $principal, float $annualRatePercent, int $months): float
{
$r = $annualRatePercent / 12 / 100;
if ($r == 0.0) {
return $principal / $months;
}
$factor = (1 + $r) ** $months;
return $principal * $r * $factor / ($factor - 1);
}
$loan = 500000;
$emi = monthlyEmi($loan, 9, 60);
$totalPaid = $emi * 60;
echo "EMI: ₹" . number_format($emi, 2) . "\n";
echo "Total paid: ₹" . number_format($totalPaid, 2) . "\n";
echo "Total interest: ₹" . number_format($totalPaid - $loan, 2) . "\n";
Output
EMI: ₹10,379.18
Total paid: ₹622,750.66
Total interest: ₹122,750.66
How It Works
- The annual rate (9%) is converted to a monthly decimal rate:
9 / 12 / 100 = 0.0075. - The EMI formula is
P × r × (1 + r)^n / ((1 + r)^n − 1). (1 + r)^nis calculated once and stored in$factor, which avoids repeating the same calculation.- A zero-interest loan would cause division by zero in the formula, so it is handled separately.
These results are suitable for display and estimates. For actual financial records, banks apply specific rounding rules per installment; such systems use integer paise or BCMath (see PHP Floats).
Distance Between Two Coordinates (Haversine Formula)
<?php
function distanceKm(float $lat1, float $lon1, float $lat2, float $lon2): float
{
$earthRadiusKm = 6371;
$dLat = deg2rad($lat2 - $lat1);
$dLon = deg2rad($lon2 - $lon1);
$a = sin($dLat / 2) ** 2
+ cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon / 2) ** 2;
return 2 * $earthRadiusKm * asin(sqrt($a));
}
$chennai = [13.0827, 80.2707];
$bengaluru = [12.9716, 77.5946];
echo round(distanceKm(...$chennai, ...$bengaluru), 1) . " km\n";
Output
290.2 km
How It Works
- The haversine formula calculates the shortest distance over the Earth's surface (the "as the crow flies" distance) between two latitude/longitude points.
- Coordinates are in degrees, so differences are converted to radians with
deg2rad()before usingsin()andcos(). ...$chennaiunpacks the array into separate arguments (see Variadic Functions).- The Earth's mean radius is about 6371 km. Road distance is longer; this formula gives straight-line distance, which is used for "stores near you" features and delivery radius checks.
Basic Statistics
<?php
function mean(array $values): float
{
return array_sum($values) / count($values);
}
function median(array $values): float
{
sort($values);
$count = count($values);
$middle = intdiv($count, 2);
return $count % 2 === 0
? ($values[$middle - 1] + $values[$middle]) / 2
: $values[$middle];
}
function standardDeviation(array $values): float
{
$avg = mean($values);
$squaredDiffs = array_map(fn($v) => ($v - $avg) ** 2, $values);
return sqrt(array_sum($squaredDiffs) / count($values));
}
$deliveryDays = [12, 15, 11, 18, 14];
echo "Mean: " . mean($deliveryDays) . "\n";
echo "Median: " . median($deliveryDays) . "\n";
echo "Std deviation: " . round(standardDeviation($deliveryDays), 2) . "\n";
Output
Mean: 14
Median: 14
Std deviation: 2.45
How It Works
- Mean — the sum divided by the count (
70 / 5 = 14). - Median — the middle value after sorting (
11, 12, 14, 15, 18→14). For an even count, it is the average of the two middle values. The median is less affected by extreme values than the mean. - Standard deviation — how far values typically spread from the mean. Each difference from the mean is squared, the squares are averaged, and the square root of that average is taken. This is the population standard deviation.
sort()insidemedian()works on a copy, because arrays are passed by value; the caller's array keeps its original order.- These functions assume a non-empty array. In production code, check for empty input first to avoid
DivisionByZeroError.
Common Mistakes
Passing Degrees to Trigonometric Functions
Effect: sin(30) treats 30 as radians and returns about -0.988.
Fix: sin(deg2rad(30)).
Expecting Integer Results From sqrt(), round(), floor(), or ceil()
Effect: The result is a float, which can cause type errors or deprecation notices when used as an array index or an int argument.
Fix: Cast explicitly: (int) sqrt(144), (int) ceil($x).
Calling max() or min() on an Empty Array
Effect: ValueError in PHP 8.
Fix: Check that the array is not empty, or provide a default value.
Forgetting Division-by-Zero Cases
Effect: DivisionByZeroError in percentage changes, averages, and formulas with a rate of zero.
Fix: Handle zero denominators explicitly, as in monthlyEmi().
Using % With Decimals
Effect: 7.5 % 2 converts operands to integers (with a deprecation notice since PHP 8.1) and returns 1, not 1.5.
Fix: Use fmod().
Relying on Float Results for Money
Effect: Small rounding differences in totals and installments.
Fix: Format for display only; use integers in the smallest unit or BCMath for stored financial values.
Best Practices
- Use
max(min, min(max, value))to clamp user input into valid ranges. - Convert degrees to radians before using trigonometric functions.
- Round only when displaying results; keep full precision during calculations.
- Guard every division against a zero denominator.
- Use
array_sum()witharray_column()to total fields from records. - Use BCMath or GMP when exact decimal results or very large numbers are required.
Official reference: https://www.php.net/manual/en/ref.math.php