Mathematics7 min readExamples run on PHP 8.5.10

abs()

Learn how PHP 8.4 abs() returns the absolute value of an int or float, how its return type follows the input, and which edge cases and mistakes to avoid.

Signature

abs(int|float $num): int|float

Purpose

abs() returns the absolute value of a number: its distance from zero, with the sign removed. A negative number becomes positive, and a positive number or zero stays as it is. It is useful whenever only the size of a value matters, such as the gap between two measurements, the error of an estimate, or the magnitude of a change.

Signature

Parameters and defaults

abs() takes a single parameter, $num, which is the numeric value to process. It has no default value, so you must always pass an argument. The declared type is int|float.

Without declare(strict_types=1), PHP's usual coercion applies to scalar arguments. A numeric string such as "-5" is converted to a number before the calculation. Non-numeric strings are rejected.

Return value and failure cases

The return type follows the argument:

  • If you pass a float, you get a float.
  • If you pass an int, you get an int.

If the argument cannot be used as int|float, for example the string "abc", PHP throws a TypeError. Since PHP 8.0.0, abs() no longer accepts internal objects that support numeric conversion.

Example 1: the basic behavior

This example shows the sign being removed and the type being preserved.

Example
<?php
var_dump(abs(-4.2));
var_dump(abs(5));
var_dump(abs(-5));
Output
float(4.2)
int(5)
int(5)

Example 2: distance between two values

A common use is measuring how far apart two numbers are without caring which one is larger. Subtract them and take the absolute value.

Example
<?php
function distance(int|float $a, int|float $b): int|float
{
    return abs($a - $b);
}

echo json_encode([distance(3, 10), distance(10, 3), distance(2.5, 4.0)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[7,7,1.5]

The order of the arguments does not change the result. When both inputs are integers the result is an integer, and a float input makes the result a float.

Example 3: edge cases

The following code checks the result types for a few unusual inputs, then shows a failure.

Example
<?php
$values = [abs(PHP_INT_MIN), abs(-0.0), abs("-5"), abs(-7.0)];
echo json_encode(array_map('get_debug_type', $values), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";

try {
    abs("abc");
} catch (TypeError $e) {
    echo "TypeError\n";
}
Output
["float","float","int","float"]
TypeError

Edge cases

  • PHP_INT_MIN: On a 64-bit build, the positive counterpart of the smallest integer does not fit in an int. The result is therefore a float, as shown above. This is the one case where an integer input does not produce an integer result.
  • Negative zero: abs(-0.0) returns a float zero with the sign cleared.
  • Numeric strings: In coercive typing mode, "-5" becomes the integer 5. A numeric string with a decimal point is treated as a float.
  • Non-numeric strings: These throw a TypeError rather than silently producing 0.

Common mistakes

  1. Expecting rounding. abs() only changes the sign. abs(-4.7) is 4.7, not 5. Use a separate rounding function if you need whole numbers.
  2. Assuming the result is always an int. If the input might be a float, or might be PHP_INT_MIN, the result can be a float. Declare return types as int|float where it matters.
  3. Applying it too early. Taking abs() of each value before combining them is different from taking it of the combined result. abs(-3) + abs(5) is 8, while abs(-3 + 5) is 2.
  4. Forgetting that the sign is lost. If direction matters, such as profit versus loss, store the sign separately before calling abs().
  5. Passing unvalidated input. Text from forms or files may not be numeric. Validate it first or be ready to handle a TypeError.
  6. Using it for arbitrary-precision numbers. abs() works with native PHP numbers. For GMP numbers, use gmp_abs() instead.
  • gmp_abs() returns the absolute value of a GMP number.
  • gmp_sign() returns the sign of a GMP number, which helps when you need the direction that abs() discards.

Recap

abs() accepts one int|float and returns its non-negative magnitude. Integers stay integers and floats stay floats, except that PHP_INT_MIN overflows into a float. It does not round, and it throws a TypeError for non-numeric strings. It is the right tool for distances, differences and error magnitudes.

Tested examples

Basic abs() behavior and returned types
<?php
var_dump(abs(-4.2));
var_dump(abs(5));
var_dump(abs(-5));
Output
float(4.2)
int(5)
int(5)
Distance between two values
<?php
function distance(int|float $a, int|float $b): int|float
{
    return abs($a - $b);
}

echo json_encode([distance(3, 10), distance(10, 3), distance(2.5, 4.0)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[7,7,1.5]
Edge cases: result types and TypeError
<?php
$values = [abs(PHP_INT_MIN), abs(-0.0), abs("-5"), abs(-7.0)];
echo json_encode(array_map('get_debug_type', $values), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";

try {
    abs("abc");
} catch (TypeError $e) {
    echo "TypeError\n";
}
Output
["float","float","int","float"]
TypeError