比较精度降低的浮点数列表

时间:2016-12-06 19:01:18

标签: floating-point common-lisp precision floating-accuracy

我正在编写一个执行重浮点数计算的函数的测试。当然,在计算花车时,您不希望得到完全准确的结果。然而,这对我的测试来说是个问题,因为我需要将预期结果与函数产生的实际结果进行比较。

我的功能结果是花车的列表。例如:

(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))))

这有效,但不是很优雅。

2 个答案:

答案 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也提供双浮动......