Comparing Inexact Values

Before discussing this, the first rule is: avoid dealing with inexact values if at all possible. Scheme has the ability to deal with rationals very nicely, and they should be very strongly preferred.

That being said, if you must use inexact numbers, you are no longer able to use equal? to compare results exactly because of inaccuracies caused by floating-point truncation. Unfortunately, there is no particularly good alternative.

A First Attempt

Say you want to check within what looks like a reasonable error threshold; you may want to try a function like this:

#lang scheme

(provide check-close)

(define (check-close arg1 arg2)
    [(or (not (number? arg1)) (not (number? arg2))) false]
    [else (<= (abs (- arg1 arg2)) .001)]))

The problem is that this does not scale with the size of the expected result. A return value of 34289054363421236.54321 in a calculation involving multiplication and/or division has very little margin for error, whereas a result like .0000056789 allows for a very large amount of error to be made in the computation.

A Second Attempt

We can instead scale the allowed error according to the size of the anticipated result.

(define (approximately-equal-helper expected result (percent-diff 1/10))
  (and (number? expected) (number? result)
       (let* ((mult-factor (/ percent-diff 100))
              (expected-deviation (* expected mult-factor))
              (extreme-pt-1 (+ expected expected-deviation))
              (extreme-pt-2 (- expected expected-deviation))
              (max-acceptable (max extreme-pt-1 extreme-pt-2))
              (min-acceptable (min extreme-pt-1 extreme-pt-2)))
         (<= min-acceptable result max-acceptable))))

where percent-diff can be provided by a wrapping function if desired.

Topic revision: r1 - 2010-03-04 - TerryVaskor
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback