【发布时间】:2011-08-02 21:56:02
【问题描述】:
我的方法如下
def myMethod(myDouble: Double): Double = myDouble match {
case Double.NaN => ...
case _ => ...
}
IntelliJ 调试器显示 NaN,但在我的模式匹配中没有发现。是否有可能我省略的情况
【问题讨论】:
标签: scala pattern-matching ieee-754 nan
我的方法如下
def myMethod(myDouble: Double): Double = myDouble match {
case Double.NaN => ...
case _ => ...
}
IntelliJ 调试器显示 NaN,但在我的模式匹配中没有发现。是否有可能我省略的情况
【问题讨论】:
标签: scala pattern-matching ieee-754 nan
根据 IEEE 754(与 Scala 甚至 Java 无关,请参阅 NaN)比较 64 位浮点数是一般规则:
double n1 = Double.NaN;
double n2 = Double.NaN;
System.out.println(n1 == n2); //false
想法是NaN 是unknown 或indeterminate 的标记值。比较两个未知值应该总是得到false,因为它们很好......未知。
如果你想对NaN 使用模式匹配,试试这个:
myDouble match {
case x if x.isNaN => ...
case _ => ...
}
但我认为模式匹配会使用严格的双重比较,所以要小心这个结构。
【讨论】:
NaN != NaN 在许多(如果不是全部)编程语言中向程序员公开了这个值。
.isNaN 的速度只有 java.lang.Double.isNaN 的一半左右,因此在紧密循环中应该首选后者。 (匹配与 if 语句一样快。)为了清楚起见(即除了严格的性能关键循环之外的所有地方),.isNaN 形式可能是最好的。
你可以写一个提取器(根据bse的评论更新):
object NaN {
def unapply(d:Double) = d.isNaN
}
0.0/0.0 match {
case NaN() => println("NaN")
case x => println("boring " + x)
}
//--> NaN
【讨论】:
object NaN { def unapply(d:Double) = d.isNaN }。可以这样使用:0.0/0.0 match { case NaN() => print("NaN") }
托马斯是正确的。你应该改用isNaN。
scala> Double.NaN.isNaN
res0: Boolean = true
【讨论】: