MIT 6.5151 course code base based on book Software Design for Flexibility has the following definition:
(define (close-enuf? h1 h2 tolerance)
(n:<= (n:magnitude (n:- h1 h2))
(n:* .5
(n:max tolerance flo:ulp-of-one)
(n:+ (n:magnitude h1)
(n:magnitude h2)
2.))))
Here n:foo
means foo
in internal Scheme implementation as the book says:
Because we anticipated varying the meanings of many operators
in the MIT/GNU Scheme system, we made a special set of
operators that name primitive procedures we might need later.
We named the copies with the prefix n:. In MIT/GNU Scheme
the original primitive procedures are always available, with their
original names, in the system-global-environment, so we
could have chosen to get them from there.
If only considering real numbers, then the above returns |h1-h2|<=((|h1|+|h2|+2)/2)*tolerance
when tolerance
is not very small. Here tolerance may mean relative tolerance as python math.isclose
and this JS implementation instead of absolute tolerance as this QA implies.
But as the definition implies, if |h1|+|h2|
is very big, then the result may probably return true. So (close-enuf? 1e4 (+ 1 1e4) 1e-4)
will return #t
.
Then why does the course code base define such a close-enuf?
? Does it work better for some cases?