Jaki jest idiomatyczny sposób na sprawdzenie, czy dwie liczby są blisko siebie w Clojure?Jak sprawdzić, czy dwie liczby są blisko Clojure
Gdzieś wzdłuż linii:
(deftest sqrt-test
(is (~= 1.414 (Math/sqrt 2)))
Jaki jest idiomatyczny sposób na sprawdzenie, czy dwie liczby są blisko siebie w Clojure?Jak sprawdzić, czy dwie liczby są blisko Clojure
Gdzieś wzdłuż linii:
(deftest sqrt-test
(is (~= 1.414 (Math/sqrt 2)))
Musisz określić "blisko". Jeśli poprosisz o „różnicy” mniejszej niż jakiś tolerancji, można toczyć własną funkcję używając <
:
(defn close? [tolerance x y]
(< (difference x y) tolerance))
Jeżeli różnica może być bezwzględna:
(defn absolute-difference ^double [^double x ^double y]
(Math/abs (double (- x y))))
lub względna:
(defn relative-difference ^double [^double x ^double y]
(/ (Math/abs (- x y))
(max (Math/abs x) (Math/abs y))))
(wybierz preferowaną definicję względnej różnicy, oczywiście).
Następnie testujemy przybliżoną równość z tolerancją 0,001.
Aby odkryć ograniczenia użytecznych wartości parametru tolerancji, można użyć metody Math/ulp
, która jest metodą statyczną, która przyjmuje wartość podwójną i zwraca bezwzględną różnicę między nią a najmniejszym większym podwójnym.
Chociaż jak roztwór Michał Marczyka zauważyć, że nie jest już
ok =
funkcję zdefiniowaną clojure.algo.generic.math grupy funkcyjne. Przykładowe użycie:
clojuree.o=> (approx= 1.41 (sqrt 2) 1e-2)
true
clojuree.o=> (approx= 1.41 (sqrt 2) 1e-4)
false