在 a 和 b 之间生成双打
generate doubles between a and b
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
}
}
}
输出
+ Gen Doubles.normalize: OK, passed 100 tests.
! Gen Doubles.between: Falsified after 0 passed tests.
> ARG_0: 2.9635128477431505E249
> ARG_1: 1.807071439895287E-167
我的数学哪里不及格?
编辑解决方案:
val ascendingTuple = (for {
a <- Arbitrary.arbitrary[Double]
b <- Arbitrary.arbitrary[Double]
} yield(a, b))suchThat({case (a, b) => a < b})
问题是您没有强制要求 b
应该大于 a
,但是您的测试假定了这一点。当 b
的生成值小于 a
时,您会得到一个 b <= f <= a
的数字,这将导致您的测试失败。要进行简单修复,请尝试:
forAll(between(a, b)) { f =>
if (a < b) {
a <= f && f <= b
} else {
b <= f && f <= a
}
}
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
}
}
}
输出
+ Gen Doubles.normalize: OK, passed 100 tests.
! Gen Doubles.between: Falsified after 0 passed tests.
> ARG_0: 2.9635128477431505E249
> ARG_1: 1.807071439895287E-167
我的数学哪里不及格?
编辑解决方案:
val ascendingTuple = (for {
a <- Arbitrary.arbitrary[Double]
b <- Arbitrary.arbitrary[Double]
} yield(a, b))suchThat({case (a, b) => a < b})
问题是您没有强制要求 b
应该大于 a
,但是您的测试假定了这一点。当 b
的生成值小于 a
时,您会得到一个 b <= f <= a
的数字,这将导致您的测试失败。要进行简单修复,请尝试:
forAll(between(a, b)) { f =>
if (a < b) {
a <= f && f <= b
} else {
b <= f && f <= a
}
}