X-Git-Url: http://git.kpe.io/?p=kmrcl.git;a=blobdiff_plain;f=math.lisp;h=c03b27f5d54238e5cfc1a48df0e43d7e3d3d5f8c;hp=e9118443fdec24c716cf21898b42615ce5973692;hb=4b512145081c369cb1dbfe579a4dfd5a32476b92;hpb=e2b92d341da89f35b96f8ea5437bab0ec1d590f7 diff --git a/math.lisp b/math.lisp index e911844..c03b27f 100644 --- a/math.lisp +++ b/math.lisp @@ -73,3 +73,38 @@ (defun fixnum-width () (nth-value 0 (truncate (+ (/ (log (1+ most-positive-fixnum)) (log 2)) .5)))) + +(defun scaled-epsilon (float &optional (operation '+)) + "Return the smallest number that would return a value different from + FLOAT if OPERATION were applied to FLOAT and this number. OPERATION + should be either + or -, and defauls to +." + (multiple-value-bind (significand exponent) + (decode-float float) + (multiple-value-bind (1.0-significand 1.0-exponent) + (decode-float (float 1.0 float)) + (if (and (eq operation '-) + (= significand 1.0-significand)) + (scale-float (typecase float + (short-float short-float-negative-epsilon) + (single-float single-float-negative-epsilon) + (double-float double-float-negative-epsilon) + (long-float long-float-negative-epsilon)) + (- exponent 1.0-exponent)) + (scale-float (typecase float + (short-float short-float-epsilon) + (single-float single-float-epsilon) + (double-float double-float-epsilon) + (long-float long-float-epsilon)) + (- exponent 1.0-exponent)))))) + +(defun sinc (x) + (if (zerop x) + 1d0 + (let ((x (coerce x 'double-float))) + (/ (sin x) x)))) + + +(defun numbers-within-percentage (a b percent) + "Determines if two numbers are equal within a percentage difference." + (let ((abs-diff (* 0.01 percent 0.5 (+ (abs a) (abs b))))) + (< (abs (- a b)) abs-diff)))