diff --git a/qd-fun.lisp b/qd-fun.lisp index 9564dccc374d5f34387f117431ae913fac4420ae..207a51b93e758228226214609f0da54851ceeee3 100644 --- a/qd-fun.lisp +++ b/qd-fun.lisp @@ -1188,7 +1188,10 @@ is the cosine of A" ;; atan(x) = pi/2-atan(1/x), for x > 1 (sub-qd +qd-pi/2+ (atan-qd/taylor (div-qd +qd-one+ y)))) + ((qd-<= y (aref octi::+qd-atan-partition+ 0)) + (atan-taylor y)) (t + ;; The general case where the table is needed. (let* ((i (find-atan-partition y)) (atan-xi (mul-qd +qd-pi/2+ (rational-to-qd (/ (1- (+ i 2)) @@ -1244,6 +1247,8 @@ is the cosine of A" (neg-qd +qd-pi/4+)))) (let ((arg (atan-qd/taylor (div-qd y (abs-qd x))))) + ;; arg = atan2(y,|x|), so |arg| <= pi/2. Handle the case when x + ;; is negative. (cond ((minusp-qd x) (if (minusp-qd y) (- (neg-qd +qd-pi+) arg) @@ -1254,12 +1259,12 @@ is the cosine of A" (defun atan2-qd (y x) "atan2(y, x) = atan(y/x), but carefully handling the quadrant" (declare (type %quad-double y x)) - (atan2-qd/newton y x)) + (atan2-qd/taylor y x)) (defun atan-qd (y) "Return the arc tangent of the %QUAD-DOUBLE number Y" (declare (type %quad-double y)) - (atan-qd/newton y)) + (atan-qd/taylor y)) (defun asin-qd (a) "Return the arc sine of the %QUAD-DOUBLE number A" diff --git a/rt-tests.lisp b/rt-tests.lisp index 69f6ee7c7bb54b34dae794a14ab117353c65c859..289131e246b1e9e110892d23fffef5d71887a2c4 100644 --- a/rt-tests.lisp +++ b/rt-tests.lisp @@ -222,6 +222,9 @@ nil) (rt:deftest oct.atan.4 + ;; We know atan(10^100) is pi/2 because atan(10^100) = + ;; pi/2-atan(10^-100) and atan(10^-100) is approx 10^-100, which + ;; is too small to affect pi/2. (let* ((arg #q1q100) (y (/ (atan arg) +pi+)) (true #q.5))