The Existential Crisis of NaN: We Are Not the Same
Why is this CS Fundamentals meme funny?
Level 1: Two Mystery Boxes
Imagine you have two closed mystery boxes and you have no idea what’s inside either one. They might each contain a surprise, or nothing at all – you just don’t know. Now, if someone asks you, “Do these two boxes have the same thing inside?”, what would you say? You’d probably shrug and reply, “I’m not sure, I can’t tell.” You definitely wouldn’t confidently say “yes, they’re the same” because, well, they’re mysteries!
That’s basically what’s happening with NaN. NaN is like a label that means “I don’t know what this number is.” If one value is NaN and another value is also NaN, it’s like two mystery boxes. The computer says, “I won’t claim these are equal, because I honestly don’t know what they are.” It treats each NaN as its own unknown thing. So even though both boxes are mysterious, the system won’t declare them a match. It’s a bit funny because we see “not a number” on both and think, “hey, they look the same!” but the computer is very literal – unknown isn’t equal to unknown.
The meme puts this in a silly way: two people both say “I am NaN” (I am not a number), yet one says to the other “we are not the same.” It’s like two classmates both refusing to answer a question and then insisting their non-answers are completely different. It makes us laugh because in everyday life if two people say “I don’t know,” they kind of are giving the same response. But in computer logic, each “I don’t know” stands alone. The computer won’t assume one unknown equals another unknown. So, the joke is highlighting that strict attitude: even when two values are both “NaN,” the computer stubbornly says, “Nope, they’re not equal.” It’s a quirky rule, but it’s how computers keep surprises (or errors) from causing even more confusion. The result? A meme-worthy moment where two identical-looking values proudly declare, “we are not the same!”
Level 2: NaN is Not NaN
Let’s break down the joke in simpler terms. NaN stands for “Not a Number.” It’s a special value used in many programming languages to indicate “this result is not a real number.” You typically get a NaN when you do an undefined mathematical operation. For example:
- Dividing 0 by 0 (
0/0) doesn’t produce a real number, so the computer gives a NaN. - Taking the square root of a negative number (in a system that isn’t handling complex numbers) yields NaN.
- In JavaScript, trying to convert the string
"hello"into a number withNumber("hello")results in NaN, because “hello” isn’t a numeric value.
Think of NaN as a flag that something went mathematically wrong or is undefined. It’s like the computer’s way of saying, “I can’t give you a meaningful number for this, so here’s Not-a-Number instead.”
Now, the equality operator (the == or === in code) is normally how we check if two values are the same. For instance, 5 === 5 is true, and "cat" === "cat" is true. We would expect that if we have two things that look the same, the equality check would say true. But NaN is a weird exception. According to the rules that virtually all languages follow, NaN is never equal to NaN when you use the normal equality checks. This is exactly what the meme text jokes about: “I am NaN, you are NaN, we are not the same.” It’s saying both values are NaN, yet value1 == value2 would come out false. It feels illogical, right? It’s as if two identical twins looked at each other and a judge declared, “Nope, not a match.”
Let’s see it in action with a quick JavaScript example:
let a = NaN;
let b = NaN;
console.log(a === b); // false -> Even though a and b are both NaN
console.log(a == b); // false -> Same result with loose equality
console.log(Number.isNaN(a)); // true -> This is the correct way to check for NaN in JS
Here, a and b are two variables, each assigned NaN. Logging a === b prints false. The computer literally says they’re not equal. The third line shows the proper way to check for NaN in JavaScript: Number.isNaN(a) returns true, meaning “yes, a is a NaN”. We have to use a special function because the normal == or === check won’t work for NaN. In Python, you’d do something similar:
import math
x = float('nan')
y = float('nan')
print(x == y) # False -> NaN compared to NaN is not equal
print(math.isnan(x)) # True -> x is NaN
This prints False for the equality check, but True when using the math.isnan() function that specifically checks for NaNs. Pretty much every language has a special way to test for NaN because of this quirk.
Why was it designed this way? The idea is that NaN means “I don’t have a real value.” If you ask, “are these two no-values the same?”, the safe answer is “no, we can’t assume they are.” It’s a bit like asking, “Is unknown equal to unknown?” We simply don’t know if whatever made one NaN is the same as what made the other NaN. So the computer errs on the side of not equating them. It’s a language quirk that surprises people. In fact, beginners often write code like if (x == NaN) and find it never ever runs, even when x is actually NaN. The correct approach, as shown above, is to use functions like Number.isNaN(x) or math.isnan(x) depending on the language.
One more JavaScript oddity related to this is the difference between isNaN() and Number.isNaN(). The older global isNaN() will try to be clever and convert things to a number first. So isNaN("hello") returns true, because “hello” becomes NaN behind the scenes. This was confusing, so modern JS added Number.isNaN() which doesn’t do any type coercion – it only returns true if the value is actually a NaN. For example:
console.log(isNaN("hello")); // true -> "hello" becomes NaN, then isNaN reports true
console.log(Number.isNaN("hello")); // false -> "hello" is not a number and not NaN as a value
console.log(Number.isNaN(NaN)); // true -> correctly identifies NaN
The key takeaway: NaN is a special case. It doesn’t behave like a normal number (even though it’s usually treated as a kind of number in the type system). The meme text is funny to us because it literally spells out this special case in a meme-y way. Both the man in the picture and the one he’s addressing are labeled NaN, but the caption declares “WE ARE NOT THE SAME,” nodding to the fact that in code, NaN !== NaN. If you ever see a snippet like if (x !== x) and wonder why someone would do that, now you know: it’s a clever trick to check for NaN, because only NaN fails to equal itself.
So, in summary: NaN is a numeric wildcard meaning “not a real number result,” and by rule, it never equals anything — not even another NaN. When you need to see if something is NaN, you have to use dedicated checks. It’s a little counterintuitive, but it’s one of those CS fundamentals about floating-point arithmetic that, once you learn it, makes you chuckle at memes like this. The language designers chose this behavior to avoid confusion between error values, and ironically created a new point of confusion for learners. But hey, at least it gives us great meme material!
Level 3: NaN Identity Crisis
In practice, this meme hits home for experienced developers because it lampoons a classic language quirk. We’ve all been there: debugging some code, scratching our heads at an if condition that never passes, only to realize we were comparing a variable to NaN. The meme’s text spells it out plainly:
I AM NaN
YOU ARE NaN
WE ARE NOT THE SAME.
It’s a humorous dramatization of the moment you discover that two values which look identical (NaN and NaN) still fail an equality check. The developer brain does a double-take: “Wait, these two things are not equal… even though they’re both NaN?!” It feels like an identity crisis for the value – how can something not equal itself? – which is exactly what’s going on.
This is a shared gotcha across many languages (JavaScript, Python, Java, C, you name it) because they all follow the IEEE-754 floating-point rules under the hood. The scenario is so common that it’s become a CS folklore of sorts. For example, in JavaScript you might see code like:
let value = 0/0; // Produces NaN (undefined result)
console.log(value); // NaN
console.log(value === NaN); // false -> Oops, checking NaN this way doesn’t work!
A junior dev might initially try if (value === NaN) as a check, expecting it to catch the “not-a-number” case. But the equality operator stubbornly returns false, so that branch never runs. It’s the classic “NaN is the one value that is never equal to itself” problem. The meme’s joke exaggerates this by personifying two NaN values in suits asserting they’re different people. It’s like two identical twins insisting they’re not related – absurd in human terms, but that’s essentially what our code is doing with NaNs.
Language gotchas abound here. In JavaScript, NaN is actually of type “number” (typeof NaN === 'number' is true, a little irony on its own), yet it’s a special kind of number that fails all comparisons. Trying to find a NaN in an array with indexOf won’t work ([NaN].indexOf(NaN) returns -1, as if NaN isn’t in the array at all) because the comparison always says “not equal”. Newer JavaScript methods introduced fixes: Array.includes uses a SameValueZero comparison so that it can honestly report a NaN is present, and Object.is(NaN, NaN) was added to safely check for NaN equality (it returns true for two NaNs, unlike ===). These were responses to how annoying this quirk can be in real coding scenarios.
Other languages have their own tales: In Python, float('nan') == float('nan') is False as well. Seasoned Python devs know to use math.isnan(x) or x != x to check for NaNs. In Java or C#, Double.NaN == Double.NaN is false, so the standard library provides an isNaN() function. In C, if you mistakenly do something like:
double x = 0.0/0.0; // NaN in C
if(x == x) {
printf("Equal\n");
} else {
printf("Not equal\n");
}
// This will print "Not equal"
you’ll see “Not equal” printed, confirming the weird reality. Many static analysis tools and linters will actually warn you if you compare to NaN, because it’s almost always a logic error. As the meme hints, the equality operator is effectively telling you “those two NaNs? Not the same.”
This resonates with senior developers because we’ve learned (often the hard way) why this design exists. It prevents unreliable comparisons with invalid data. Imagine if NaNs compared true just because they’re both “not real numbers” – it could mask errors. We want NaNs to propagate and loudly fail checks so we don’t accidentally treat a garbage result as valid. The downside is, of course, the confusion and bugs it causes when you’re unaware of the rule. The meme winks at all the debugging sessions spent figuring out why a filter wasn’t filtering or why a calculation kept returning NaN without triggering an alert.
There’s also a bit of dark humor here relating to how computers handle “unknown” values in general. It’s akin to how SQL treats NULL – if you compare NULL == NULL in a database query, you don’t get true; you get NULL (unknown), because each NULL is “unknown data”. Likewise, NaN means “I don’t have a real number for you,” and two unknowns aren’t assumed equal. This is by design, or as devs jokingly say, “Not a bug, a feature.” The meme’s Impact-font proclamation “WE ARE NOT THE SAME” is basically the equality operator’s official stance on NaNs. It’s funny because the two NaNs appear identical in every way, yet one line of code (a === b) confidently declares them different. Every experienced coder who’s dealt with floating-point arithmetic recognizes this little absurdity and probably smirks, recalling the first time it baffled them.
Ultimately, the meme highlights an infamous edge case that unites CS fundamentals with daily coding reality. It’s a playful reminder that in computing, two wrongs don’t make a right – and two NaNs don’t make an equal. After you’ve been burned by this once, you never forget it. Now we can all laugh, seeing a stone-faced man in a suit declaring this ridiculous truth: in code, “I am NaN, you are NaN, and yet... we are not the same.”
Level 4: Reflexivity Rejected
NaN (Not-a-Number) defies one of the fundamental laws of equality – it’s not reflexive. In theoretical terms, an equality relation is supposed to be reflexive (meaning any value x should satisfy x == x). But the IEEE-754 floating-point standard explicitly breaks this rule for NaN. According to IEEE-754, if either operand in a comparison is NaN, the comparison is unordered and considered false (except for the “not equal” operator, which is defined true when comparing NaN to anything, including another NaN). This design decision was deliberate: NaN represents an “undefined” or unrepresentable numeric result, so the standard deems it illogical to claim one undefined value is equal to another undefined value. In other words, each NaN is treated as a unique missing piece of information, so assuming two unknowns are the same is unsafe.
Under the hood, a floating-point NaN isn’t a single canonical value but a whole family of bit patterns. For an IEEE-754 64-bit double, any pattern with all exponent bits = 1 and a non-zero fraction field is a NaN. This means there are many possible NaN representations (with different “payloads” of information). For example, one NaN might arise from a division by zero, another from an overflow, each carrying a slightly different binary pattern. If the equality operator tried to consider all NaNs equal, it would effectively be conflating distinct error states. By making every NaN != NaN, the standard avoids false assumptions that two different undefined results are meaningfully the same. It’s a bit like a safeguard: don’t trust one unknown to equal another unknown.
This non-reflexive equality has interesting logical consequences. It violates the traditional properties of an equivalence relation (no reflexivity, so equality isn’t an equivalence when NaN is in the domain). It also breaks the trichotomy law of comparisons: normally for any two real numbers a and b, one (and only one) of {a < b, a == b, a > b} is true. Introduce NaN, and none of those comparisons return true! The IEEE-754 spec defines this scenario as “unordered”. Hardware implements this by having comparison operations produce a false result if a NaN is involved, often raising a processor flag to signal “unordered comparison” if needed. High-level languages simply reflect this: every direct comparison with NaN fails.
Paradoxically, IEEE-754 does the opposite for zero: it defines a positive zero 0.0 and a negative zero -0.0 as two distinct bit patterns that do compare equal (+0 == -0 yields true, treating both as just “0”). This was done to preserve mathematical expectations (since in math, -0 and +0 are the same number). So floating-point arithmetic has this quirky symmetry: it merges values that are physically different (two zeros with different signs are considered equal) and distinguishes values that appear the same (two NaNs are considered unequal). The meme’s humor arises from this latter quirk – it’s highlighting a case where our normal notion of equality is stood on its head by design.
In academic terms, NaN comparison semantics prevent any accidental reasoning that an invalid result might equal another invalid result. The only reliable check for NaN is to ask explicitly “is this not-a-number?” via specialized functions or conditions. In fact, one infamous trick leverages the reflexivity violation: if x != x is true, you know x must be NaN (no legitimate number is ever unequal to itself). This bit of logical jiu-jitsu is a direct consequence of IEEE-754’s rules. Far from being a bug, it’s a feature born from deep computer science fundamentals and decades of floating-point design. The meme distills that complex reality into a punchline: two identical-looking values that boldly declare, “WE ARE NOT THE SAME,” perfectly capturing the inside joke of NaN’s unexpected equality behavior.
Description
This meme uses the popular 'We Are Not the Same' format, which features actor Giancarlo Esposito as the character Gus Fring from 'Breaking Bad'. He is shown in a sharp suit, adjusting his tie with a stern, confident look. The meme is cleverly adapted for a deep-cut computer science joke. The top text reads, 'I AM NaN'. The middle text says, 'YOU ARE NaN'. The punchline at the bottom is, 'WE ARE NOT THE SAME'. The humor is rooted in the IEEE 754 standard for floating-point arithmetic, which is used in almost all modern programming languages. A core, and often perplexing, property of the special value 'NaN' (Not a Number) is that it is not equal to any other value, including itself. Therefore, a comparison like `NaN === NaN` will always evaluate to `false`. The meme perfectly captures this technical absurdity, as the statement 'we are not the same' is literally true, even if both values are NaN
Comments
15Comment deleted
The first rule of NaN club is: you do not equal yourself. The second rule of NaN club is: you DO NOT equal yourself
IEEE-754 taught me that even two NaNs in the same register refuse to acknowledge equality - exactly how our microservice teams behave when someone whispers “schema v2.0.”
After 20 years in this industry, I've accepted that JavaScript's NaN behavior is like that one microservice in production - technically correct according to IEEE 754, universally acknowledged as confusing, yet somehow critical to the entire ecosystem's backwards compatibility that we're all too afraid to fix
The only value in JavaScript that practices radical individualism so thoroughly it refuses to equal even itself - NaN is the ultimate non-conformist, breaking the reflexive property of equality and causing senior engineers to add 'Number.isNaN()' checks everywhere like paranoid type guards, because apparently 'NaN === NaN' returning false wasn't enough of a footgun for the TC39 committee
Only in IEEE-754 can two identical failures be unique keys; NaN !== NaN, so your dedupe job just doubled the customer base
NaN !== NaN: floating-point's eternal reminder that self-awareness is overrated in production metrics
Pro tip: when deduping by a float key, you’ll either get infinite NaNs in Python sets or exactly one in a JS Set - define the equality contract before your data pipeline discovers metaphysics
But we are both numbers Comment deleted
Nope. We are not. Comment deleted
Yes you are both instance of numbers Comment deleted
A im NaN you are "NaN" Comment deleted
cries in ieee 754 Comment deleted
Teeextrakt Comment deleted
? Comment deleted
Intrusive thoughts when I say the I tripple E again Comment deleted