From: Lutz Euler <leuler@us...>  20130828 21:10:17

The branch "master" has been updated in SBCL: via 69a917778bad1b3c82a8cdd511097adf11a1531a (commit) from adaba39fb52f52487bd1a1b632b735e59045e19d (commit)  Log  commit 69a917778bad1b3c82a8cdd511097adf11a1531a Author: Lutz Euler <lutz.euler@...> Date: Wed Aug 28 23:09:05 2013 +0200 Improve the test float.impure.lisp / (RANGEREDUCTION PRECISEPI). The way the test calculated its expected values was flawed and worked correctly only accidentally due to the specific test values used and to allowing a relatively large margin of error. This commit corrects these calculations, removes some test values and adds others and tightens the error margin. I do not expect this to cause the test's outcome on any platform to change. The flaw was to reduce the arguments by taking the remainder of truncating modulo 2 pi. This allows precise calculations only of the sine and the tangent of values slightly above even multiples of pi, but not for example for the sine of an argument near an odd multiple of pi. Instead the reduction is now done by taking the remainder of rounding to the nearest multiple of pi/2 so that all arguments near the zeroes of both sine and cosine reduce to values near zero. This change was prompted when the test unexpectedly failed with some values from gcc bug 43490 which I tried when investigating lp #1137924.  tests/float.impure.lisp  69 ++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 18 deletions() diff git a/tests/float.impure.lisp b/tests/float.impure.lisp index 29ca23b..621520e 100644  a/tests/float.impure.lisp +++ b/tests/float.impure.lisp @@ 303,28 +303,53 @@ fractional bits." ;; (:rangereduction :x87) above. (withtest (:name (:rangereduction :precisepi) :skippedon :x86)  (let ((rational2pi (* 2 (pigausslegendre 2200))))  (labels ((mod2pi (x)  "Return X modulo 2 pi, where pi is precise enough that the  result is exact to doublefloat precision for all possible  doublefloat arguments." + (let ((rationalpihalf (/ (pigausslegendre 2200) 2))) + (labels ((roundpihalf (x) + "Return two values as if (ROUND X (/ PI 2)) was called + but where PI is precise enough that for all possible + doublefloat arguments the quotient is exact and the + remainder is exact to doublefloat precision." (declare (type doublefloat x))  (coerce (mod (rational x) rational2pi)  'doublefloat)) + (multiplevaluebind (q r) + (round (rational x) rationalpihalf) + (values q (coerce r 'doublefloat)))) + (expectedval (op x) + "Calculate (OP X) precisely by shifting the argument by + an integral multiple of (/ PI 2) into the range from + ( (/ PI 4)) to (/ PI 4) and applying the phaseshift + formulas for the trigonometric functions. PI here is + precise enough that the result is exact to doublefloat + precision." + (labels ((preciseval (op q r) + (ecase op + (sin (let ((x (if (zerop (mod q 2)) + (sin r) + (cos r)))) + (if (<= (mod q 4) 1) + x + ( x)))) + (cos (preciseval 'sin (1+ q) r)) + (tan (if (zerop (mod q 2)) + (tan r) + (/ ( (tan r)))))))) + (multiplevaluebind (q r) + (roundpihalf x) + (preciseval op q r)))) (test (op x) (let ((actual (funcall op x))  (expected (funcall op (mod2pi x))))  ;; Some of the test values are chosen to reduce modulo  ;; 2 pi to small numbers (between 1d10 and 1d7),  ;; making their sine and tangent this small, too.  ;; For other test values the absolute value of the  ;; tangent may be much larger than 1. Therefore we + (expected (expectedval op x))) + ;; Some of the test values are chosen to lie very near + ;; to an integral multiple of pi/2 (within a distance of + ;; between 1d11 and 1d8), making the absolute value of + ;; their sine or cosine this small, too. The absolute + ;; value of the tangent is then either similarly small or + ;; as large as the reciprocal of this value. Therefore we ;; measure relative instead of absolute error. (unless (or (= actual expected 0) (and (= (signum actual) (signum expected)) (< (abs (/ ( actual expected) (+ actual expected)))  (/ 1d12 2)))) + (* 8 doublefloatepsilon)))) (error "Inaccurate result for ~a: expected ~a, got ~a" (list op x) expected actual))))) (dolist (op '(sin cos tan)) @@ 333,8 +358,16 @@ fractional bits." then (expt v 4/5) while (> v (expt 2 50)) collect v)  6.543554061677196d28  1.5334254929660437d43  1.837213298702053d93  4.913896894631919d229)) + ;; The following values cover all eight combinations + ;; of values slightly below or above integral + ;; multiples of pi/2 with the integral factor + ;; congruent to 0, 1, 2 or 3 modulo 4. + 5.526916451564098d71 + 4.913896894631919d229 + 7.60175752894437d69 + 3.8335637324151093d42 + 1.8178427396473695d155 + 9.41634760758887d89 + 4.2766818550391727d188 + 1.635888515419299d28)) (test op val))))))  hooks/postreceive  SBCL 