Signature
intdiv(int $num1, int $num2): intPurpose
intdiv() divides one integer by another and gives you only the whole-number part of the result. Unlike the / operator, it never produces a float, so the return type is always int. It is the right tool when you are counting how many complete groups fit into a total: full pages, whole hours in a number of minutes, complete boxes in a shipment.
Signature
Parameters and defaults
$num1: the dividend, the number being divided.$num2: the divisor, the number that divides$num1.
Neither parameter is optional and there are no defaults. Both are declared as int, so pass integers. Under PHP's default coercive typing, numeric strings and some floats may be converted, but it is clearer and safer to cast explicitly before calling.
Return value and failure cases
The function returns the quotient with the fractional part discarded. The result is truncated toward zero, not rounded and not floored. Two situations throw an exception instead of returning:
- If
$num2is0, aDivisionByZeroErroris thrown. - If
$num1isPHP_INT_MINand$num2is-1, anArithmeticErroris thrown, because the true result does not fit in a PHP integer.
Because DivisionByZeroError is a kind of ArithmeticError, catching ArithmeticError handles both.
Example 1: truncation toward zero
The sign of the operands decides the sign of the result, and the fraction is simply cut off.
echo json_encode([
intdiv(7, 2),
intdiv(-7, 2),
intdiv(7, -2),
intdiv(-7, -2),
]), PHP_EOL;[3,-3,-3,3]
Seven divided by two is 3.5, which becomes 3. With a negative operand, 3.5 becomes -3, not -4. That is the key difference from floor().
Example 2: pagination with a remainder
intdiv() pairs naturally with the % operator. Together they split a total into whole groups and what is left over.
function paginate(int $items, int $perPage): array
{
$full = intdiv($items, $perPage);
$rest = $items % $perPage;
return ['fullPages' => $full, 'remaining' => $rest, 'pages' => $full + ($rest > 0 ? 1 : 0)];
}
echo json_encode(paginate(45, 10)), PHP_EOL;
echo json_encode(paginate(40, 10)), PHP_EOL;{"fullPages":4,"remaining":5,"pages":5}
{"fullPages":4,"remaining":0,"pages":4}
For positive numbers, the number of pages is the quotient plus one when any items remain.
Example 3: handling errors
Wrap the call when the divisor comes from outside your code, such as user input or a configuration value.
function attempt(int $a, int $b): string
{
try {
return (string) intdiv($a, $b);
} catch (ArithmeticError $e) {
return get_class($e) . ': ' . $e->getMessage();
}
}
echo attempt(10, 3), PHP_EOL;
echo attempt(1, 0), PHP_EOL;
echo attempt(PHP_INT_MIN, -1), PHP_EOL;3 DivisionByZeroError: Division by zero ArithmeticError: Division of PHP_INT_MIN by -1 is not an integer
The second call reports a DivisionByZeroError, and the third reports an ArithmeticError for the one overflowing combination.
Edge cases
- Dividend smaller than divisor:
intdiv(1, 5)returns0, and a negative dividend such asintdiv(-1, 5)also gives0, because truncation toward zero never produces negative zero for integers. - Relationship with
%: for valid inputs,intdiv($a, $b) * $b + $a % $bequals$a. The remainder from%takes the sign of the dividend, which matches the truncating behavior ofintdiv(). - Same value on both sides:
intdiv(PHP_INT_MIN, PHP_INT_MIN)is1. Only the-1divisor withPHP_INT_MINoverflows. - Large values: because both inputs and the result are integers, there is no loss of precision from float conversion, which can happen with
floor($a / $b)on very large numbers.
Common mistakes
- Expecting floor behavior. Developers used to mathematical floor division are surprised that
intdiv(-7, 2)is-3. If you need rounding toward negative infinity, use a different approach and test negative inputs deliberately. - Using
/and assuming an int. The/operator returns an int only when the division is exact; otherwise it returns a float. Useintdiv()when you always want an integer. - Passing fractional floats. Hand
intdiv()real integers. Cast with(int)on purpose, so the truncation is visible in your code rather than a side effect of conversion. - Forgetting to guard the divisor. A divisor read from data can be zero. Validate it or catch the error.
- Ignoring the
PHP_INT_MINcase. It is rare, but code that processes arbitrary integers should be aware of it.
Related functions and operators
/performs ordinary division and may return a float.%returns the integer remainder.fmod()returns the floating-point remainder.floor()rounds a float down toward negative infinity.
Recap
intdiv($a, $b) returns the whole-number quotient of two integers, truncating toward zero. It always returns an int, throws DivisionByZeroError when the divisor is zero, and throws ArithmeticError for PHP_INT_MIN divided by -1. Combine it with % when you need both the quotient and the remainder.
Tested examples
echo json_encode([
intdiv(7, 2),
intdiv(-7, 2),
intdiv(7, -2),
intdiv(-7, -2),
]), PHP_EOL;[3,-3,-3,3]
function paginate(int $items, int $perPage): array
{
$full = intdiv($items, $perPage);
$rest = $items % $perPage;
return ['fullPages' => $full, 'remaining' => $rest, 'pages' => $full + ($rest > 0 ? 1 : 0)];
}
echo json_encode(paginate(45, 10)), PHP_EOL;
echo json_encode(paginate(40, 10)), PHP_EOL;{"fullPages":4,"remaining":5,"pages":5}
{"fullPages":4,"remaining":0,"pages":4}
function attempt(int $a, int $b): string
{
try {
return (string) intdiv($a, $b);
} catch (ArithmeticError $e) {
return get_class($e) . ': ' . $e->getMessage();
}
}
echo attempt(10, 3), PHP_EOL;
echo attempt(1, 0), PHP_EOL;
echo attempt(PHP_INT_MIN, -1), PHP_EOL;3 DivisionByZeroError: Division by zero ArithmeticError: Division of PHP_INT_MIN by -1 is not an integer