В Scala почему NaN не обнаруживается при сопоставлении с образцом? - PullRequest
29 голосов
/ 02 августа 2011

Мой метод следующий:

  def myMethod(myDouble: Double): Double = myDouble match {
    case Double.NaN => ...
    case _ => ...
  }

Отладчик IntelliJ показывает NaN, но это не обнаруживается при сопоставлении с моим шаблоном.Есть ли возможные случаи, которые я пропускаю

Ответы [ 3 ]

45 голосов
/ 02 августа 2011

Общее правило сравнения 64-битных чисел с плавающей запятой согласно IEEE 754 (не относится к Scala или даже к Java, см. NaN ):

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

Идеяявляется то, что NaN является значением маркера для неизвестно или неопределено .Сравнение двух неизвестных значений должно всегда давать false, поскольку они хорошо ... неизвестны.


Если вы хотите использовать сопоставление с шаблоном с NaN, попробуйте это:

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

Но я думаю, что для сопоставления с образцом будет использовано строгое двойное сравнение, поэтому будьте осторожны с этой конструкцией.

12 голосов
/ 02 августа 2011

Вы можете написать экстрактор (обновляется в соответствии с комментариями bse):

object NaN {
  def unapply(d:Double) = d.isNaN
}


0.0/0.0 match {
  case NaN() => println("NaN")
  case x => println("boring " + x)
}
//--> NaN
4 голосов
/ 02 августа 2011

Томаш прав. Вы должны использовать isNaN вместо.

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