【问题标题】:In Scala, why is NaN not being picked up by pattern matching?在 Scala 中,为什么模式匹配没有选择 NaN?
【发布时间】: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


    【解决方案1】:

    根据 IEEE 754(与 Scala 甚至 Java 无关,请参阅 NaN)比较 64 位浮点数是一般规则:

    double n1 = Double.NaN;
    double n2 = Double.NaN;
    System.out.println(n1 == n2);     //false
    

    想法是NaNunknownindeterminate 的标记值。比较两个未知值应该总是得到false,因为它们很好......未知。


    如果你想对NaN 使用模式匹配,试试这个:

    myDouble match {
        case x if x.isNaN => ...
        case _ => ...
    }
    

    但我认为模式匹配会使用严格的双重比较,所以要小心这个结构。

    【讨论】:

    • +1 指出 NaN != NaN 在许多(如果不是全部)编程语言中向程序员公开了这个值。
    • 请注意,如果大多数数字不是 NaN,.isNaN 的速度只有 java.lang.Double.isNaN 的一半左右,因此在紧密循环中应该首选后者。 (匹配与 if 语句一样快。)为了清楚起见(即除了严格的性能关键循环之外的所有地方),.isNaN 形式可能是最好的。
    【解决方案2】:

    你可以写一个提取器(根据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") }
    【解决方案3】:

    托马斯是正确的。你应该改用isNaN

    scala> Double.NaN.isNaN
    res0: Boolean = true
    

    【讨论】:

      猜你喜欢
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      相关资源
      最近更新 更多