Skip to content

Instantly share code, notes, and snippets.

@treyharris
Created July 28, 2019 22:09
Show Gist options
  • Save treyharris/8107f960637ad7e6fb59696b2ce81a1b to your computer and use it in GitHub Desktop.
Save treyharris/8107f960637ad7e6fb59696b2ce81a1b to your computer and use it in GitHub Desktop.

Fuzzy matching of any numeric type

In Elisp: Numbers (Comparison of Numbers), a suggested definition of approx-equal is given as:

(defvar fuzz-factor 1.0e-6)
(defun approx-equal (x y)
  (or (= x y)
      (< (/ (abs (- x y))
            (max (abs x) (abs y)))
         fuzz-factor)))

I was breiefly surprised after evaluating this to find that (approx-equal 2 22) returned t. But then I realized the issue: in this case, the (< (/ ... fuzz-factor)) was performing integer division, and here, the result will almost certainly be 0, which is < fuzz-factor.

So here's a naïve attempt to fix this:

(defun approx-equal (fx fy)
  (let ((x (float fx))
      (y (float fy))
      )
    (or (= x y)
      (< (/ (abs (- x y))
            (max (abs x) (abs y)))
         fuzz-factor))))

It works, but is there a more idiomatic way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment