Нахождение хорошего решения этой проблемы было одним из первых вопросов, с которыми я столкнулся, когда начал работать с Clojure много лет назад. Я создал функцию rel=
в библиотеке Tupelo именно для этой цели:
(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 )))