Introduction
NaN (Not-a-Number) and infinity are special floating-point values defined by the IEEE 754 standard. NaN represents undefined or unrepresentable results (like 0/0), while infinity represents values that exceed the maximum representable number. Every major language provides constants or functions to create and check for these values. Understanding their behavior is essential because NaN has unusual comparison properties — it is not equal to itself — and arithmetic with infinity follows specific rules.
Python
1import math
2
3# NaN
4nan_val = float('nan')
5nan_val2 = math.nan # Python 3.5+
6nan_val3 = float('NaN') # Case-insensitive
7
8# Infinity
9inf_val = float('inf')
10neg_inf = float('-inf')
11inf_val2 = math.inf # Python 3.5+
12
13# Checking for NaN and infinity
14print(math.isnan(nan_val)) # True
15print(math.isinf(inf_val)) # True
16print(math.isinf(neg_inf)) # True
17print(math.isfinite(42.0)) # True
18print(math.isfinite(inf_val)) # False
19print(math.isfinite(nan_val)) # False
20
21# NaN is NOT equal to itself
22print(nan_val == nan_val) # False
23print(nan_val != nan_val) # True
NumPy
1import numpy as np
2
3nan_val = np.nan
4inf_val = np.inf
5
6arr = np.array([1.0, np.nan, 3.0, np.inf, -np.inf])
7print(np.isnan(arr)) # [False, True, False, False, False]
8print(np.isinf(arr)) # [False, False, False, True, True]
9
10# Replace NaN with a value
11cleaned = np.nan_to_num(arr, nan=0.0, posinf=999, neginf=-999)
12print(cleaned) # [1.0, 0.0, 3.0, 999.0, -999.0]
JavaScript
1// NaN
2let nanVal = NaN;
3let nanVal2 = Number.NaN;
4let nanVal3 = parseInt("hello"); // NaN
5let nanVal4 = 0 / 0; // NaN
6
7// Infinity
8let infVal = Infinity;
9let negInf = -Infinity;
10let infVal2 = Number.POSITIVE_INFINITY;
11let negInf2 = Number.NEGATIVE_INFINITY;
12let infVal3 = 1 / 0; // Infinity
13
14// Checking
15console.log(Number.isNaN(nanVal)); // true
16console.log(Number.isFinite(infVal)); // false
17console.log(Number.isFinite(42)); // true
18
19// IMPORTANT: use Number.isNaN, not global isNaN
20console.log(isNaN("hello")); // true (coerces string)
21console.log(Number.isNaN("hello")); // false (no coercion)
22
23// NaN is not equal to itself
24console.log(NaN === NaN); // false
25console.log(Object.is(NaN, NaN)); // true (ES6)
Java
1// NaN
2double nanVal = Double.NaN;
3float nanFloat = Float.NaN;
4
5// Infinity
6double infVal = Double.POSITIVE_INFINITY;
7double negInf = Double.NEGATIVE_INFINITY;
8double infCalc = 1.0 / 0.0; // Infinity (double division)
9
10// Checking
11System.out.println(Double.isNaN(nanVal)); // true
12System.out.println(Double.isInfinite(infVal)); // true
13System.out.println(Double.isFinite(42.0)); // true
14
15// NaN comparisons
16System.out.println(nanVal == nanVal); // false
17System.out.println(Double.isNaN(nanVal)); // true (use this instead)
C / C++
1#include <math.h>
2#include <float.h>
3
4// NaN
5double nan_val = NAN; // C99 macro
6double nan_val2 = nan(""); // Function
7
8// Infinity
9double inf_val = INFINITY; // C99 macro
10double inf_val2 = 1.0 / 0.0;
11
12// Checking
13printf("isnan: %d\n", isnan(nan_val)); // 1
14printf("isinf: %d\n", isinf(inf_val)); // 1
15printf("isfinite: %d\n", isfinite(42.0)); // 1
1// C++
2#include <cmath>
3#include <limits>
4
5double nan_val = std::numeric_limits<double>::quiet_NaN();
6double inf_val = std::numeric_limits<double>::infinity();
7
8std::cout << std::isnan(nan_val) << std::endl; // 1
9std::cout << std::isinf(inf_val) << std::endl; // 1
C# / .NET
1// NaN
2double nanVal = double.NaN;
3float nanFloat = float.NaN;
4
5// Infinity
6double posInf = double.PositiveInfinity;
7double negInf = double.NegativeInfinity;
8
9// Checking
10Console.WriteLine(double.IsNaN(nanVal)); // True
11Console.WriteLine(double.IsInfinity(posInf)); // True
12Console.WriteLine(double.IsPositiveInfinity(posInf)); // True
13Console.WriteLine(double.IsFinite(42.0)); // True (.NET Core 2.1+)
Arithmetic Rules
1import math
2
3inf = float('inf')
4nan = float('nan')
5
6# Infinity arithmetic
7print(inf + 1000) # inf
8print(inf + inf) # inf
9print(inf - inf) # nan
10print(inf * 0) # nan
11print(inf * 2) # inf
12print(inf * -1) # -inf
13print(1 / inf) # 0.0
14
15# NaN arithmetic — NaN propagates
16print(nan + 1) # nan
17print(nan * 5) # nan
18print(nan == nan) # False
19print(nan > 0) # False
20print(nan < 0) # False
21
22# Comparisons with infinity
23print(inf > 1e308) # True
24print(-inf < -1e308) # True
Practical Uses
1# Use infinity as initial min/max values
2def find_min(values):
3 result = float('inf')
4 for v in values:
5 if v < result:
6 result = v
7 return result
8
9print(find_min([5, 3, 8, 1])) # 1
10
11# Use NaN as a missing data sentinel
12import pandas as pd
13data = pd.Series([1.0, float('nan'), 3.0, float('nan'), 5.0])
14print(data.mean()) # 3.0 (NaN ignored by default)
15print(data.dropna()) # [1.0, 3.0, 5.0]
Common Pitfalls
Checking NaN with ==: NaN == NaN is False in every language — this is defined by IEEE 754. Always use math.isnan() (Python), Number.isNaN() (JavaScript), Double.isNaN() (Java), or std::isnan() (C++) to check for NaN.
Using JavaScript's global isNaN() instead of Number.isNaN(): The global isNaN("hello") returns true because it coerces the string to a number first. Number.isNaN("hello") correctly returns false. Always use Number.isNaN() for accurate NaN checks.
Integer division producing infinity in some languages: In Python, 1 / 0 raises ZeroDivisionError, not infinity. Only floating-point division 1.0 / 0.0 produces infinity in C/Java. In JavaScript, 1 / 0 gives Infinity because all numbers are floats.
NaN in sorting and comparisons: NaN is not less than, greater than, or equal to any value (including itself). Sorting arrays containing NaN produces unpredictable results. Filter out NaN values before sorting.
Serializing NaN and infinity to JSON: JSON does not support NaN, Infinity, or -Infinity. Python's json.dumps(float('nan')) raises ValueError with allow_nan=False, or produces non-standard output. Replace special values before serialization.
Summary
Use float('nan') / math.nan (Python), NaN (JavaScript), Double.NaN (Java/C#) to create NaN
Use float('inf') / math.inf (Python), Infinity (JavaScript), Double.POSITIVE_INFINITY (Java/C#) for infinity
Always use language-specific functions to check for NaN — never use == because NaN is not equal to itself
NaN propagates through all arithmetic operations
Infinity follows algebraic rules except inf - inf = NaN and inf * 0 = NaN
Filter NaN values before sorting, aggregating, or serializing to JSON