I came across a golang quiz which used NaN as a maps key and it ran without any error. If map's keys are supposed to be comparable is NaN a comparable type or is this a compiler bug which allowed NaN as a key.
Here's the quiz source, the go playground link and code below.
package main
var x = 0.0
func main() {
var a = x / x // a = NaN
var m = map[float64]int{a: 1}
m[a] = 2
for k := range m {
delete(m, k)
}
println(len(m)) // prints 2
}
CodePudding user response:
The short answer is that this is not a compiler bug.
Maps require comparable types as keys. Float (regardless of float32 or float64) is a comparable type. What's odd about NaN (and in a different way, zero, which can be either positive or negative zero) is that while you can compare two NaNs, they always compare as unequal. So some float value x
is not equal to itself when x
is NaN. This produces surprises.
Issue 20660 comments note that the same kind of problems occur in a number of other languages.
I particularly like Russ Cox's comment that there are only bad answers here.
CodePudding user response:
Thanks @torek for pointing out the outstanding issue
https://github.com/golang/go/issues/20660
It answered my question.
CodePudding user response:
According to the documentation , math.NaN returns a float64 which is a comparable type
CodePudding user response:
Any float64 is comparable. There is no problem comparing any two floats. You can compare a NaN to 3.141 or NaN to NaN.
The problem is not comparability if NaNs/floats. The problem is that any comparison of a NaN with anything, even an other NaN or itself will result in false.
NaN != x for all x, including NaN
This makes using NaNs as map keys basically impossible because it's impossible to find a NaN.