在a和b之间产生双打

时间:2015-11-10 22:05:04

标签: scala scalacheck

import org.scalacheck._
import org.scalacheck.Prop._

object Doubles extends Properties("Gen Doubles") {
  val positiveDouble = Arbitrary.arbitrary[Double] suchThat (_ > 0.0)
  val normalize = Arbitrary.arbitrary[Double] map (f => math.abs(f) / Double.MaxValue)
  def between(a: Double, b: Double) = normalize map (_ * (b - a) + a)
  property("normalize") = forAll(normalize) { f => 0.0 <= f && f <= 1.0 }
  property("between") = forAll(positiveDouble, positiveDouble) { (a: Double, b: Double) =>
    forAll(between(a, b)) { f =>
      a <= f && f <= b
    }
  }
}

通过http://scastie.org/13056输出

+ Gen Doubles.normalize: OK, passed 100 tests.

! Gen Doubles.between: Falsified after 0 passed tests.
> ARG_0: 2.9635128477431505E249
> ARG_1: 1.807071439895287E-167

我的数学失败在哪里?

EDIT解决方案:

val ascendingTuple = (for {
  a <- Arbitrary.arbitrary[Double]
  b <- Arbitrary.arbitrary[Double]
} yield(a, b))suchThat({case (a, b) => a < b})

1 个答案:

答案 0 :(得分:1)

问题在于,您并未强制b应大于a,但您的测试假定为此。如果b的生成值小于a,则会得到一个b <= f <= a的数字,这会使您的测试失败。要进行简单的修复,请尝试:

forAll(between(a, b)) { f =>
  if (a < b) {
    a <= f && f <= b
  } else {
    b <= f && f <= a
  }
}