is_nan
Checks whether a float is NAN, the value that comparison operators can never detect.
is_nan(float $num): bool- Added in PHP 4.2.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$num | float | The float value to check. |
Return value
booltrue if num is NAN, false otherwise.
See also
That breaks every comparison-based idiom in the language: in_array(), array_search(), array_keys() with a search value, and switch will all fail to find a NAN sitting right in front of them. (array_unique() is the exception, and only by accident: its default SORT_STRING flag compares the string casts, and every NAN casts to "NAN", so duplicates are collapsed after all.)
Example
When to use it
- Filtering sensor or import data before averaging, so one bad reading does not make the mean NAN.
- Validating the result of sqrt(), acos() or asin() when the argument came from user input.
- Rejecting a division result computed with fdiv() where both operands could be zero.
- Debugging why a numeric column suddenly renders as the string NAN in a report.
Frequently asked questions
Why does NAN == NAN return false in PHP?
IEEE-754 defines NAN as unordered, so it compares unequal to every value including itself. That is precisely why PHP provides is_nan(): no comparison operator can detect a NAN.
How do I remove NAN values from an array?
Use array_filter($arr, fn($v) => !is_nan($v)), then array_values() if you need a re-indexed list. in_array() and array_search() both fail on NAN because they rely on comparison. array_unique() is not a counter-example to be relied on: it defaults to SORT_STRING and compares the string casts, so it does collapse repeated NANs — but it cannot remove them from the array.
What is the difference between NAN and null in PHP?
null is the absence of a value and has its own type, while NAN is a genuine float produced by an undefined arithmetic operation. is_null() and is_nan() are not interchangeable, and passing null to is_nan() is a deprecated implicit conversion rather than a meaningful check.
More examples
Where NAN comes from
Every one of these is an operation with no defined answer, so IEEE-754 says the result is NAN rather than an error. None of them raises a warning or throws, which is exactly why a NAN can travel a long way through an application before anyone notices.
<?php
$cases = [
'sqrt(-1)' => sqrt(-1),
'INF - INF' => INF - INF,
'INF / INF' => INF / INF,
'fdiv(0,0)' => fdiv(0, 0),
'0.0 * INF' => 0.0 * INF,
'acos(2)' => acos(2),
];
foreach ($cases as $label => $v) {
printf("%-10s => %-6s is_nan: %s\n", $label, var_export($v, true), is_nan($v) ? 'true' : 'false');
}Filtering NAN out of a dataset
in_array() cannot find the NANs because it compares, and NAN compares equal to nothing. array_sum() returns NAN for the whole array, so the naive mean prints NAN. Filtering with is_nan() leaves three valid readings whose mean is 12.00 — note the array_values() call, since array_filter() preserves keys.
<?php
$readings = [12.5, NAN, 8.0, NAN, 15.5];
var_dump(in_array(NAN, $readings, true)); // false, even though two are there
printf("naive mean: %s\n", var_export(array_sum($readings) / count($readings), true));
$valid = array_values(array_filter($readings, fn($v) => !is_nan($v)));
print_r($valid);
printf("clean mean: %.2f\n", array_sum($valid) / count($valid));
Discussion