From ... From: Erik Naggum Subject: Re: equality of floating point numbers Date: 1997/03/04 Message-ID: <3066494244824844@naggum.no>#1/1 X-Deja-AN: 223074591 References: <331C4855.3E0B@uwaterloo.ca> mail-copies-to: never Organization: Naggum Software; +47 2295 0313; http://www.naggum.no Newsgroups: comp.lang.lisp * Kevin Mayall | A friend recently gave me a crash-course in the issues of computing the | equality of floating-point numbers. I've written functions such as f=, | f<, f>, etc., which use an epsilon value to test for fp equality. I want | to make these into CLOS methods on =, <, >, etc., for arguments of the | class, Float (that way, I don't have to worry about whether I'm calling | the fp or non-fp function). I'm led to believe this is common practice | in CL. | | So my question is how do CL programmers generally hide these fp functions | so that they may be used via the regular =, <, >, etc. functions? if they do this, they do it by creating a new package that inherits from the "COMMON-LISP" package and then shadows the relevant functions. they also define a methods that do not take objects of type float. (defpackage :fuzzy (:use :common-lisp) (:shadow "=" "<" "<=" ">" ">=" "zerop") (:export "=" "<" "<=" ">" ">=" "zerop")) (in-package :fuzzy) (defconstant epsilon 1e-4) (cl:< (- epsilon) x epsilon)) (defun = (x y) (cl:< (- epsilon) (- x y) epsilon)) (defun < (x y) (cl:< (- x y) epsilon)) (defun <= (x y) (cl:<= (- x y) epsilon)) (defun > (x y) (cl:> (- x y) (- epsilon))) (defun >= (x y) (cl:>= (- x y) (- epsilon))) (of course, you know how to do the fuzzy comparisons better than I do, and the above might not even be correct implementations, but this should only illustrate how the package system may be used.) note that the comparison functions in the COMMON-LISP package all take any number of arguments. you may wish to implement this functionality if you run "normal" code, since it is quite common to test for ranges with, e.g., (< low x high). if you do, note that (OP x y z...) is the same as (and (OP x y) (OP y z...)) for all OPs _except_ /=. #\Erik -- if you think big enough, you never have to do it