Floating numbers and equivalence

The other day I spotted an interesting thread on Twitter regarding this equivalence of NaN (Not-a-number) being wrong in Clojure

(let [x ##NaN] (not= x x))
0.1s

No suprise here, but let's check the second part as suggested in the Tweet

(defn nan? [x] (not= x x))
(nan? ##NaN)
0.0s

So what's going on there?

(defn fixed-nan? [^double x] (not= x x))
(fixed-nan? ##NaN)
0.1s

So it seems that general comparison does not cover path where boxed NaN values are compared with not= operator

(let [x ##NaN] (not (= x x)))
0.0s

There is a summary with an advice here: https://clojure.org/guides/equality

'Not a Number' values ##NaNFloat/NaN, and Double/NaN are not = or == to anything, not even themselves. Recommendation: Avoid including ##NaN inside of Clojure data structures where you want to compare them to each other using =, and sometimes get true as the result.

And actually there is an explanation with all the details in this section https://clojure.org/guides/equality#_floating_point_not_a_number

Thank you for reading.

Runtimes (1)