From 9d4e07e51cba263c5c4e68634baf932b62d7b368 Mon Sep 17 00:00:00 2001 From: "Thomas M. Hermann" Date: Thu, 4 Mar 2010 15:32:38 -0600 Subject: [PATCH] Corrected the 1.0 = 0.99999 sigfig-equal bug. These values were not reported equal because the 0.99999 was not be rounded correctly. The current approach appears robust, but looks like it could be simplified. Bug found by Mirko Vukovic. --- floating-point.lisp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/floating-point.lisp b/floating-point.lisp index 5d34b07..802204a 100644 --- a/floating-point.lisp +++ b/floating-point.lisp @@ -503,16 +503,12 @@ error norm is less than epsilon." (defun %sigfig-equal (float1 float2 significant-figures) "Return true if the floating point numbers have equal significant figures." - ;; Convert 0.5 to precision of FLOAT1 and 10 to precision of FLOAT2. - ;; Then, rely on Rule of Float and Rational Contagion, CLHS 12.1.4.1, - ;; to obtain a DELTA of the proper precision. - (let ((delta (* (float 0.5 float1) (expt (float 10 float2) (- significant-figures))))) - (if (or (zerop float1) (zerop float2)) - (< (abs (+ float1 float2)) delta) - (multiple-value-bind (sig1 exp1) (%normalize-float float1) - (multiple-value-bind (sig2 exp2) (%normalize-float float2) - (and (= exp1 exp2) - (< (abs (- sig1 sig2)) delta))))))) + (if (or (zerop float1) (zerop float2)) + (< (abs (+ float1 float2)) (* 5D-1 (expt 1D1 (- significant-figures)))) + (multiple-value-bind (sig1 exp1) (%normalize-float float1) + (multiple-value-bind (sig2 exp2) (%normalize-float float2) + (= (round (* sig1 (expt 1D1 significant-figures))) + (round (* sig2 (expt 1D1 (- significant-figures (- exp1 exp2)))))))))) (defmethod sigfig-equal ((data1 float) (data2 float) &optional (significant-figures *significant-figures*)) -- 2.11.4.GIT