[英]Testing haskell equality on Doubles with HUnit?
HUnit 有什么方法可以做近似等式吗? 显然,这失败了:
test1 = TestCase (assertEqual "Should equal" (get_scores) [(0.3, 0.3), (0.6, 0.36), (1.0, 0.3399999)])
对于浮点近似比较,有一个带有一些不错的工具的库:
自从第一次提出这个问题以来, HUnit-approx
软件包已经发布。
它使用隐式变量epsilon
和近似相等运算符~?~
代替~=?
.
一个简短的例子:
tweak :: Float -> Float
tweak x = x * 1.0001
egApproxTest = let ?epsilon = 0.01 in
[ "strictEqual" ~: 0 ~=? tweak 0,
"approxEqual" ~: 2 ~?~ tweak 2 ]
注意:我不知道是否有正确/官方/可接受的方式来执行此操作。
这是 assertEqual
的源代码:
assertEqual :: (Eq a, Show a) => String -- ^ The message prefix
-> a -- ^ The expected value
-> a -- ^ The actual value
-> Assertion
assertEqual preface expected actual =
unless (actual == expected) (assertFailure msg)
where msg = (if null preface then "" else preface ++ "\n") ++
"expected: " ++ show expected ++ "\n but got: " ++ show actual
基于此以及基于JUnit的用于测试双重相等的功能 ,我们可以使用相同的样式创建自己的样式:
import Control.Monad (unless)
assertEquals :: String -- ^ The message prefix
-> Double -- ^ The maximum difference between expected and actual
-> Double -- ^ The expected value
-> Double -- ^ The actual value
-> Assertion
assertEquals preface delta expected actual =
unless (abs (expected - actual) < delta) (assertFailure msg)
where msg = ... same as above ...
就我的目的而言,此辅助功能运行良好:
assertFloatEqual text a b =
assertEqual text (take 6 (show a)) (take 6 (show b))
我将数据类型设置为等于代码的实例,以使用2个小数位。 这是使用笛卡尔点的示例:
data Point = Point { x_axis :: Double, y_axis :: Double, z_axis :: Double }
deriving (Show)
为了避免由于相同的微小差异而导致导致相同点(因此,CornerPoints)为/=
两次舍入误差和触发误差,请将其范围设置为.01
,并且仍然允许这些点相等。
axisEqual :: (Eq a, Num a, Ord a, Fractional a) => a -> a -> Bool
axisEqual a b
| (abs (a - b)) <= 0.011 = True
| otherwise = False
instance Eq Point where
Point x y z == Point xa ya za
| (axisEqual x xa) && (axisEqual y ya) &&(axisEqual z za) = True
| otherwise = False
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.