【问题标题】:clojure.test should assert the equality of two different float point number within a certain rangeclojure.test 应该断言两个不同浮点数在一定范围内的相等性
【发布时间】:2018-05-02 20:50:22
【问题描述】:

我正在使用clojure.test 进行单元测试。

一些测试失败是因为非常接近的浮点数被认为是不同的。

expected: (= expected result)
  actual: (not (= 1.0 0.9999999999999998))

expected: (= expected result)
  actual: (not (= 0.5 0.4999999999999999))

我需要指示 clojure.test 了解 (= 0.9999 1.0) 是真的。

例如,对于 NUnit,我可以使用 Is.EqualTo().Within() 来实现这一点。

注意

在我的具体情况下,1.00.999 真的是一回事。

【问题讨论】:

    标签: unit-testing clojure


    【解决方案1】:

    为这个问题找到一个好的解决方案是我多年前开始使用 Clojure 时遇到的第一个问题。我为此目的创建了rel= 函数in the Tupelo library

      (rel= val1 val2 & opts)  
      "Returns true if 2 double-precision numbers are relatively equal, 
      else false. Relative equality is specified as either (1) the N 
      most significant digits are equal, or (2) the absolute difference 
      is less than a tolerance value.  Input values are coerced to double 
      before comparison."
    

    它在行动:

    (ns tst.demo.core
      (:use demo.core tupelo.core tupelo.test))
    
    (dotest
      (is   (rel=   123450000   123456789  :digits 4 )) ; .12345 * 10^9
      (isnt (rel=   123450000   123456789  :digits 6 ))
      (is   (rel= 0.123450000 0.123456789  :digits 4 )) ; .12345 * 1
      (isnt (rel= 0.123450000 0.123456789  :digits 6 ))
    
      (is   (rel=  1  1.001  :tol 0.01   )) ; :tol value is absolute error
      (isnt (rel=  1  1.001  :tol 0.0001 )))
    

    【讨论】:

    • 太糟糕了,在 clojure.core 中没有解决方案。对我来说最简单的解决方案是编写自己的辅助函数。
    【解决方案2】:

    我在clojure.test的API中没有看到任何东西,也不想要其他依赖,所以我写了一个函数close-to

    (ns floats-test
      (:require [clojure.test :refer :all]))
    
    (defn abs
      [x]
      (max x (- x)))
    
    (defn close-to
      [x y epsilon]
      (<= (abs (- x y)) epsilon))
    
    (deftest floats...
      (testing "floats are equal"
        (is      (close-to 0.000000001 0.00000002  1e-7)))
      (testing "floats are equal (other direction)"
        (is      (close-to 0.000000002 0.00000001  1e-7)))
      (testing "floats aren't equal"
        (is (not (close-to 0.000000001 0.000001    1e-7))))
      (testing "floats aren't equal (other direction)"
        (is (not (close-to 0.000001    0.000000001 1e-7)))))
    

    【讨论】:

      猜你喜欢
      • 2014-12-19
      • 1970-01-01
      • 2015-01-28
      • 2011-11-09
      • 2017-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多