X-Git-Url: http://git.kpe.io/?p=kmrcl.git;a=blobdiff_plain;f=math.lisp;h=fcbab3c4baa2e922b0eba049af0bd04079a19739;hp=e9118443fdec24c716cf21898b42615ce5973692;hb=5470e786c59285e2f09497598505654672be847d;hpb=e2b92d341da89f35b96f8ea5437bab0ec1d590f7 diff --git a/math.lisp b/math.lisp index e911844..fcbab3c 100644 --- a/math.lisp +++ b/math.lisp @@ -73,3 +73,26 @@ (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))))))