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)
(cond
[(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.