ScalaTest Scalactic - 自定义双相等性,容差包括 Double.NaN 情况

ScalaTest Scalactic - Custom Double Equality with tolerance including Double.NaN case

提问人:ele 提问时间:7/31/2018 最后编辑:ele 更新时间:8/3/2018 访问量:1165

问:

我正在尝试创建一个自定义匹配器,该匹配器将考虑 Double.NaN 并将对非 nan 值使用容差。

import org.scalactic.{Equality, TolerantNumerics}
import org.scalatest.Matchers

trait MoreMatchers extends Matchers {

  implicit def doubleEqWithNaNAndTol: Equality[Double] = new Equality[Double] {

    implicit val tolerance: Equality[Double] = TolerantNumerics.tolerantDoubleEquality(1e-6)

    def areEqual(expected: Double, actual: Any): Boolean = actual match {
      case number: Double if number.isNaN => expected.isNaN
      case _: Double => actual === expected
      case _ => false
    }

  }

不幸的是,它不起作用。

assert(0.00226685508536916 === 0.0022668550853691587)  // failure - doesn't use tolerance
assert (Double.NaN === Double.NaN )  // success

如果在断言中输入容差,则如果存在 NaN,则失败。

assert(0.00226685508536916 === 0.0022668550853691587 +- 1e-6)  // success
assert (Double.NaN === Double.NaN  +- 1e-6)  // failure - can't use tolerance when NaN

如果我只是这样称呼它,那么它就可以工作了。

implicit val tolerance: Equality[Double] = TolerantNumerics.tolerantDoubleEquality(1e-6)

def eq(expected: Double, actual: Double): Boolean = expected match {
    case x if x.isNaN => actual.isNaN
    case _ => actual === expected
}

然后将其称为:

assert(eq(...,...))

我想知道是否有可能使用第一种方式让它工作。你以前遇到过这样的情况吗?您能提出任何解决方案吗?任何帮助将不胜感激:)

谢谢 电子

scala nan equality scalatest scalactic

评论


答:

0赞 ele 7/31/2018 #1

非常感谢 eirikr @d6 :),请参阅自定义平等要点中的解决方案

基本上,在上面的代码中,您需要在比较非 nan 双精度时使用,以便能够使用该比较中隐含的容差。tolerance.areEqual(expected, number)

import org.scalactic.{Equality, TolerantNumerics}
import org.scalatest.Matchers

trait MoreMatchers extends Matchers {

  implicit def doubleEqWithNaNAndTol: Equality[Double] = new Equality[Double] {

    implicit val tolerance: Equality[Double] = TolerantNumerics.tolerantDoubleEquality(1e-6)

    def areEqual(expected: Double, actual: Any): Boolean = actual match {
      case x: Double if x.isNaN => expected.isNaN
      case x: Double => tolerance.areEqual(expected, x)
      case _ => false
    }

  }

问候 电子