Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clojure.test should assert the equality of two different float point number within a certain range

I'm using clojure.test for unit testing.

Some of the tests fail because very close floating point numbers are considered differents.

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

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

I need to instruct clojure.test to understand that (= 0.9999 1.0) is true.

As an example, with NUnit I could use Is.EqualTo().Within() to achieve this.

Note

In my specific case, 1.0 and 0.999 are really the same thing.

like image 427
Gabriel Avatar asked Nov 15 '25 14:11

Gabriel


1 Answers

Finding a good solution to this problem was one of the first questions I wrestled with when I started working with Clojure many years ago. I created the rel= function in the Tupelo library for exactly this purpose:

  (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."

here it is in action:

(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 )))
like image 111
Alan Thompson Avatar answered Nov 18 '25 19:11

Alan Thompson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!