X-Git-Url: http://git.kpe.io/?p=kmrcl.git;a=blobdiff_plain;f=math.lisp;h=fcbab3c4baa2e922b0eba049af0bd04079a19739;hp=0197d52d5652a9fcdf28f117a309766fc7f9dc12;hb=e4718cf4751ba0ca9029e30f40b28d17305ed7c3;hpb=e48ac76f4b26ec24080dfaf524482a839cd84fff diff --git a/math.lisp b/math.lisp index 0197d52..fcbab3c 100644 --- a/math.lisp +++ b/math.lisp @@ -70,3 +70,29 @@ (incf (aref bins bin)))))) (values bins min max))) + +(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))))))