is_nan

Checks whether a float is NAN, the value that comparison operators can never detect.

Signature
is_nan(float $num): bool
  • Added in PHP 4.2.0

Parameters

ParameterTypeDescription
$numfloatThe float value to check.

Return value

booltrue if num is NAN, false otherwise.

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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.