Equality may perhaps be a right, but no power on earth can ever turn it into a fact.
— Honore de Balzac
You have some functions that return doubles or floats and you want to write some tests. How do you compare your results to the expected values? You can't use equality because of rounding errors, so you have to check if the values are near each other. But how near is near enough? And what if your numbers are buried inside data structures?
same/ish
is designed to help with these situations.
See the full API docs are available on cljdoc for more detailed instructions and examples. A brief summary is provided below.
In Leiningen, add the following to your :dependencies
in project.clj
:
Then in your test namespace(s), require same.core
:
(ns foo-test
(:requre [clojure.test :refer :all]
[same.core :refer [ish? zeroish?]]))
To compare two numbers, instead of using =
or ==
, use ish?
:
(defn f [x]
(* (/ 1. x) x)))
(deftest f-test
(is (ish? 1.0 (f 49.0))))
You can also compare data structures, and they will be compared element-wise, using ish?
for floating point types, ==
for other numbers, and =
for anything else:
(defn g [x]
{:a x
:b [(* x x) (Math/sqrt x)]))
(deftest g-test
(is (ish? {:a 23 :b [529 4.7958315233]}
(g 23.0))))
Clojure 1.7.0 or higher is required due to the reader conditionals required for ClojureScript support.
- Comparing Floating Point Numbers, 2012 Edition
- What Every Computer Scientist Should Know About Floating-Point Arithmetic
- Floating Point Demystified, Part 1
- Floating Point Demystified, Part 2
See CHANGELOG.md.
Contributions are welcomed, see CONTRIBUTING.md for details.
Copyright © Microsoft Corporation. All rights reserved.
Licensed under the MIT License.