Why is double.NaN not equal to itself?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
NaN means "not a number," and it behaves differently from ordinary numeric values by design. Under IEEE 754 floating-point rules, the equality operator treats any comparison involving NaN as false, including NaN == NaN.
That surprises people because most values are equal to themselves. With NaN, the point is to preserve the idea that an undefined numeric result should not silently behave like a normal number.
Where NaN Comes From
NaN is produced by invalid floating-point operations such as:
- '
0.0 / 0.0' - infinity minus infinity
- square root of a negative number in a real-number API
It is not a magic error object. It is a special floating-point bit pattern that propagates through later calculations so invalid numeric state is not lost.
Why NaN == NaN Is False
IEEE 754 defines NaN as unordered. In plain terms, it is not meaningfully comparable with numeric ordering or equality operators. That means:
- '
x == NaNis false' - '
x < NaNis false' - '
x > NaNis false'
including when x is itself NaN.
This rule is useful because it prevents invalid results from accidentally passing ordinary equality checks. If NaN compared equal like a regular value, bugs in numeric code would be easier to miss.
A Small .NET Example
The important detail is that .NET has two different comparison paths here:
- '
==follows floating-point equality rules, sodouble.NaN == double.NaNis false' - '
Equalsis a method with .NET-specific behavior, anddouble.NaN.Equals(double.NaN)returns true'
That distinction is why the safest test in application code is double.IsNaN(value).
Why Languages Keep This Behavior
At first glance, it would seem simpler if NaN equaled itself. But that would break a valuable diagnostic property. If a computation goes invalid and produces NaN, later equality checks should not accidentally treat it as a valid stable result.
For example, suppose a numeric algorithm computes two values that both become NaN because of the same invalid operation. If NaN == NaN returned true, code might wrongly conclude the outputs are consistent and acceptable.
The floating-point standard instead forces you to handle the invalid state explicitly.
Practical Guidance
If you need to know whether a floating-point value is NaN, use the dedicated helper:
The same principle exists in many languages:
- Java has
Double.isNaN - JavaScript has
Number.isNaN - Python has
math.isnan
The exact method names vary, but the rule is consistent: do not use regular equality to test for NaN.
Common Pitfalls
- Writing
value == double.NaNand expecting it to detectNaN. - Forgetting that
.Equalsand==are not identical in .NET for this case. - Treating
NaNlike a normal sentinel value instead of an invalid floating-point result. - Assuming all languages expose the same helper method even though the operator behavior is broadly similar.
- Ignoring the source of
NaNinstead of debugging the invalid arithmetic that produced it.
Summary
- '
NaNrepresents an invalid or undefined floating-point result.' - Under IEEE floating-point rules,
NaN == NaNis false. - In .NET,
double.NaN.Equals(double.NaN)is true, which is a separate method behavior. - The correct test in application code is
double.IsNaN. - The non-equality rule helps invalid numeric states propagate instead of looking like valid values.

