在Go语言中,NaN是一个可比较的类型吗?

huangapple go评论77阅读模式
英文:

Is NaN a comparable type in golang?

问题

我遇到了一个使用NaN作为映射键的golang测验,它运行时没有任何错误。如果映射的键应该是可比较的,那么NaN是可比较类型吗?还是这是一个编译器错误,允许NaN作为键。

这是测验源代码go playground链接和下面的代码。

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)) // 输出 2
}
英文:

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
}

答案1

得分: 3

任何float64类型的值都是可比较的。比较任意两个浮点数没有问题。你可以将NaN与3.141或NaN与NaN进行比较。

问题不在于NaN/浮点数的可比较性。问题在于无论是将NaN与任何其他值比较,还是将NaN与自身比较,结果都将为false。

对于所有的x,包括NaN本身,都有NaN != x。

这使得将NaN用作映射键基本上是不可能的,因为无法找到一个NaN。

英文:

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 of 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.

答案2

得分: 1

简短回答是这不是一个编译器的错误。

映射需要可比较的类型作为键。浮点数(无论是float32还是float64)是可比较的类型。关于NaN(以及以不同方式的零,可以是正零或负零),奇怪的是,虽然你可以比较两个NaN,但它们总是被认为是不相等的。所以当x是NaN时,某个浮点数值x不等于它自己。这会产生一些意外情况。

问题20660的评论指出在许多其他语言中也存在类似的问题。

我特别喜欢Russ Cox的评论,他说这里只有糟糕的答案。

英文:

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.

huangapple
  • 本文由 发表于 2022年9月21日 15:16:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/73796763.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定