logoalt Hacker News

NaN Is Weird

28 pointsby freediverlast Sunday at 6:08 PM32 commentsview on HN

Comments

cmovqtoday at 8:35 PM

> we had an unusual discussion about a Python oddity

There are so many discussions about "X language is so weird about it handles numbers!" and it's just IEEE 754 floats.

show 1 reply
AndriyKunitsyntoday at 8:30 PM

NaN that is not equal to itself _even if it's the same variable_ is not a Python oddity, it's an IEEE 754 oddity.

show 3 replies
zahlmantoday at 8:51 PM

> Last week in the Python Discord we had an unusual discussion about a Python oddity.

Oh, I missed it. But yes, this is more to do with NaN than Python.

> But, of course, you can't actually get to those values by their keys: ... That is, unless you stored the specific instance of nan as a variable:

Worth noting that sets work the same way here, although this was glossed over: you can store multiple NaNs in a set, but not the same NaN instance multiple times. Even though it isn't equal to itself, the insertion process (for both dicts and sets) will consider object identity before object equality:

  >>> x = float('nan')
  >>> {x for _ in range(10)}
  {nan}
And, yes, the same is of course true of `collections.Counter`.
show 1 reply
agwatoday at 8:24 PM

Fun fact - in C++ std::sort has undefined behavior, and can crash[1], if you try to sort a container with NaNs in it.

[1] https://stackoverflow.com/questions/18291620/why-will-stdsor...

munchlertoday at 8:41 PM

    >>> my_dict[nan] = 3
    >>> my_dict[nan]
    3
Wait, how does that work if nan isn't equal to itself?
show 1 reply
wackychtoday at 8:56 PM

Reminds me of this classic 4chan thread which started with an absurd-sounding comparison operator and ended with NaN semantic revelations.

https://archive.tinychan.net/read/prog/1176222557

jelehtoday at 8:59 PM

...reminds me that object + object is NaN:

  > {} + {}
  NaN

see https://www.destroyallsoftware.com/talks/wat

PS: Wait for it ... Watman! =8-)

kubbtoday at 8:28 PM

It would be more satisfying to learn why hash of nan is not guaranteed to be the same. It feels like a bug.

show 5 replies
kmeisthaxtoday at 8:23 PM

This is also why Rust has separate PartialEq and Eq traits - the latter is only available for types that don't have weird not-self-equal values like floating point NaNs or SQL NULLs. If you lie to Rust and create a wrapper type over f32 or f64 that has Eq, then you'd get unindexable NaN keys that just sit in your hashmap forever.

The real surprise to me is that Python can index NaN keys sometimes, at least by reference to the original NaN. I knew CPython does some Weird Shit with primitive values, so I assume it's because the hashmap is comparing by reference first and then by value.

paulddrapertoday at 8:15 PM

NaN == NaN is truly a perversion of equality.

It makes little sense that 1/0 is SIGFPE, but log(-5) is NaN in C.

And the same is true for higher level languages, and their error facilities.

What a mess.

show 3 replies
adampunktoday at 8:22 PM

NaN is weird? No, NaN is normal*, NaN PAYLOADS are weird: https://anniecherkaev.com/the-secret-life-of-nan

*This is false, NaN is weird, though maybe it needs to be. It is nowhere written arithmetic on computers must be straightforward.

show 1 reply