我正在编写一个执行重浮点数计算的函数的测试。当然,在计算花车时,您不希望得到完全准确的结果。然而,这对我的测试来说是个问题,因为我需要将预期结果与函数产生的实际结果进行比较。
我的功能结果是花车的列表。例如:
(is (my-function "arg1" "arg2")
'((0 1.0)
(1 2.0)))
将产生:
((0 1.00000014) (1 2.1)) is expected to be ((0 1) (1 2.1))
我的问题是:如何遍历alist并以降低的精度比较每个数字?
prove
允许我在比较预期结果和实际结果时指定测试函数。到目前为止,这是我的代码:
(defun compare-floats (f1 f2)
(= (round-to f1 6)
(round-to f2 6)))
(defun round-to (number &optional (precision 6))
(let ((div (expt 10 precision)))
(/ (round (* number div)) div)))
(is (my-function "arg1" "arg2")
'((0 1.0)
(1 2.0))
:test #'(lambda (expected actual)
(every #'identity
(mapcar #'(lambda (list1 list2)
(compare-floats (second list1)
(second list2)))
expected
actual))))
这有效,但不是很优雅。
答案 0 :(得分:2)
在我看来:
(every #'identity
(mapcar #'(lambda (list1 list2)
(compare-floats (second list1)
(second list2)))
expected
actual))
...可写:
(every (lambda (list1 list2)
(compare-floats (second list1) (second list2)))
actual
expected)
请注意,只要一个测试返回NIL,every
就会停止比较数字,这与原始函数中的情况不同。如果你发挥了重要的副作用,那就不同了。
至于测试花车,我会用这样的东西:
(defun floats-rougly-equal-p (f1 f2 &optional (precision 1e-6))
(< (abs (- f1 f2)) precision))
但是如果您的代码有效,请不要花太多时间寻找最优雅的方法。
答案 1 :(得分:2)
<强> LOOP 强>:
(loop for (nil a) in actual
and (nil b) in expected
always (compare-floats a b))
注意顺便说一下。 Common Lisp也提供双浮动......