Signature
is_finite(float $num): boolPurpose
is_finite() answers one question: is this number an ordinary, bounded float? PHP floats can hold three special kinds of value that are not ordinary numbers: NAN (not a number), INF (positive infinity) and -INF (negative infinity). is_finite() returns true for everything else and false for those three.
These special values usually appear after an operation that cannot produce a real result, such as taking the square root of a negative number or multiplying two very large floats. Checking with is_finite() before you store, display or accumulate a result keeps bad values from spreading through later calculations.
Signature
The function is available in PHP 8.4 as a normal built-in function with no namespace.
Parameters
$num: the value to test. It has no default, so it is required. The declared type isfloat, so integers are accepted and converted to float. Numeric strings are also accepted when strict typing is off.
Return value and failure cases
The function returns a bool:
truewhen$numis none ofNAN,INFor-INF.falsewhen$numis any of those three.
It never returns anything else. The only way to make it fail is to pass an argument that cannot be used as a float, such as an array or a non-numeric string like "abc". That raises a TypeError. Passing null to this non-nullable parameter is deprecated in modern PHP, so avoid it and check for null yourself first.
Example 1: Classifying a list of floats
The first example runs ordinary numbers and the three special values through the function. Zero and negative numbers are perfectly finite.
$values = [1.2345, 0.0, -42.5, NAN, INF, -INF];
$result = [];
foreach ($values as $value) {
$result[] = is_finite($value);
}
echo json_encode($result), PHP_EOL;[true,true,true,false,false,false]
Example 2: Where non-finite values come from
This example shows common sources: overflow, an invalid square root and float division by zero with fdiv(). A very large value that still fits in a float, like 1e308, remains finite.
$checks = [
'overflow' => 1e308 * 2,
'sqrt_negative' => sqrt(-1),
'fdiv_zero' => fdiv(1, 0),
'large_but_finite' => 1e308,
];
$report = [];
foreach ($checks as $label => $value) {
$report[$label] = is_finite($value);
}
echo json_encode($report), PHP_EOL;{"overflow":false,"sqrt_negative":false,"fdiv_zero":false,"large_but_finite":true}
Example 3: Averaging only the usable numbers
Because is_finite() takes one argument and returns a boolean, it works directly as a callback for array_filter(). The helper below ignores bad values and returns null when nothing usable remains.
function finiteAverage(array $numbers): ?float
{
$finite = array_values(array_filter($numbers, 'is_finite'));
if ($finite === []) {
return null;
}
return array_sum($finite) / count($finite);
}
var_dump(finiteAverage([2, 4.0, INF, NAN, 6]));
var_dump(finiteAverage([INF, -INF, NAN]));float(4) NULL
Edge cases
- Integers: an
intis converted to float, sois_finite(10)istrue. EvenPHP_INT_MAX + 1, which becomes a float, is finite. - Negative zero:
-0.0is finite. - Largest float:
PHP_FLOAT_MAXis finite, but doubling it overflows toINF. - NAN comparisons:
NANis never equal to anything, including itself, so$x === NANand$x == NANcannot detect it. Useis_nan()oris_finite()instead. - Strict types: with
declare(strict_types=1), integers are still accepted for a float parameter, but strings are rejected with aTypeError.
Common mistakes
- Treating
falseas "is NAN". Afalseresult only means the value isNANor infinite. If you must know which, callis_nan()oris_infinite()as well. - Comparing against
NANwith==. This never works. Use a function. - Passing non-numeric input. Validate strings and arrays before calling the function, or you will get a
TypeError. - Encoding unchecked floats as JSON.
json_encode()cannot representNANorINF, so filter or replace those values first. - Assuming division by zero returns a float value. The
/operator throwsDivisionByZeroError, whilefdiv()returnsINF,-INForNAN. Only the latter produces something foris_finite()to reject.
Related functions
is_nan()checks whether a float isNAN.is_infinite()checks whether a float isINFor-INF.fdiv()divides floats following IEEE rules, without throwing on a zero divisor.is_float()checks the type of a value, not whether it is a usable number.
Recap
is_finite() accepts a float and returns true unless the value is NAN, INF or -INF. Use it to guard results of risky math, to filter arrays of measurements and to protect output such as JSON. When you need the specific reason a value is not finite, pair it with is_nan() or is_infinite().
Tested examples
$values = [1.2345, 0.0, -42.5, NAN, INF, -INF];
$result = [];
foreach ($values as $value) {
$result[] = is_finite($value);
}
echo json_encode($result), PHP_EOL;[true,true,true,false,false,false]
$checks = [
'overflow' => 1e308 * 2,
'sqrt_negative' => sqrt(-1),
'fdiv_zero' => fdiv(1, 0),
'large_but_finite' => 1e308,
];
$report = [];
foreach ($checks as $label => $value) {
$report[$label] = is_finite($value);
}
echo json_encode($report), PHP_EOL;{"overflow":false,"sqrt_negative":false,"fdiv_zero":false,"large_but_finite":true}
function finiteAverage(array $numbers): ?float
{
$finite = array_values(array_filter($numbers, 'is_finite'));
if ($finite === []) {
return null;
}
return array_sum($finite) / count($finite);
}
var_dump(finiteAverage([2, 4.0, INF, NAN, 6]));
var_dump(finiteAverage([INF, -INF, NAN]));float(4) NULL