ScalaTest Scalactic - 具有公差的自定义双等式,包括 Double.NaN 大小写
ScalaTest Scalactic - Custom Double Equality with tolerance including Double.NaN case
我正在尝试创建一个自定义匹配器,它将考虑 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(...,...))
我想知道是否可以使用第一种方式让它工作。你以前遇到过这样的情况吗?你能提出任何解决方案吗?任何帮助将不胜感激:)
谢谢,
ele
非常感谢 eirikr @d6 :),请参阅 custom equality gist
中的解决方案
基本上,在上面的代码中,您需要在比较非 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
}
}
此致,
ele
我正在尝试创建一个自定义匹配器,它将考虑 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(...,...))
我想知道是否可以使用第一种方式让它工作。你以前遇到过这样的情况吗?你能提出任何解决方案吗?任何帮助将不胜感激:)
谢谢, ele
非常感谢 eirikr @d6 :),请参阅 custom equality gist
中的解决方案基本上,在上面的代码中,您需要在比较非 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
}
}
此致, ele