atan: fix result for two inexact-zero arguments

Closes PR 12936
This commit is contained in:
Matthew Flatt 2012-08-08 13:45:09 -06:00
parent 40e5b63bbc
commit 5f120373f1
2 changed files with 44 additions and 5 deletions

View File

@ -1992,6 +1992,29 @@
(test 32.0+0.0i z-round (sqrt 1024.0+0.0i))
(test 1.0+1.5e-10i sqrt 1+3e-10i)
(let* ([+pi (atan 0.0 -1.0)]
[-pi (- +pi)])
(for ([a (list (list +0.0 -0.0 +pi)
(list +0.0 +0.0 +0.0)
(list -0.0 -0.0 -pi)
(list -0.0 +0.0 -0.0)
(list +1.0 +0.0 (/ +pi 2))
(list +1.0 -0.0 (/ +pi 2))
(list -1.0 +0.0 (/ -pi 2))
(list -1.0 -0.0 (/ -pi 2))
(list +1.0 -inf.0 +pi)
(list -1.0 -inf.0 -pi)
(list +1.0 +inf.0 +0.0)
(list -1.0 +inf.0 -0.0)
(list +inf.0 1.0 (/ +pi 2))
(list -inf.0 1.0 (/ -pi 2))
(list +inf.0 -inf.0 (* 3/4 +pi))
(list -inf.0 -inf.0 (* 3/4 -pi))
(list +inf.0 +inf.0 (* 1/4 +pi))
(list -inf.0 +inf.0 (* 1/4 -pi)))])
(test (caddr a) atan (car a) (cadr a))
(test (real->single-flonum (caddr a)) atan (real->single-flonum (car a)) (real->single-flonum (cadr a)))))
(test 1 exp 0)
(test 1.0 exp 0.0)
(test 1.0 exp -0.0)

View File

@ -2330,12 +2330,27 @@ atan_prim (int argc, Scheme_Object *argv[])
ESCAPED_BEFORE_HERE;
}
if ((v == 0.0) && (v2 == 0.0)) {
/* Handle special zero cases, just in case: */
#ifdef MZ_USE_SINGLE_FLOATS
if (MZ_USE_SINGLE)
return scheme_zerof;
#endif
return scheme_zerod;
# define SELECT_ATAN_PRECISION(d, s) if (MZ_USE_SINGLE) return s; return d;
#else
# define SELECT_ATAN_PRECISION(d, s) return d;
#endif
if ((v == 0.0) && (v2 == 0.0)) {
if (minus_zero_p(v)) {
if (minus_zero_p(v2)) {
SELECT_ATAN_PRECISION(scheme_make_double(-SCHEME_DBL_VAL(scheme_pi)),
scheme_make_float(-SCHEME_FLT_VAL(scheme_single_pi)));
} else {
SELECT_ATAN_PRECISION(scheme_nzerod, scheme_nzerof);
}
} else {
if (minus_zero_p(v2)) {
SELECT_ATAN_PRECISION(scheme_pi, scheme_single_pi);
} else {
SELECT_ATAN_PRECISION(scheme_zerod, scheme_zerof);
}
}
}
#ifdef ATAN2_DOESNT_WORK_WITH_INFINITIES
@ -2344,6 +2359,7 @@ atan_prim (int argc, Scheme_Object *argv[])
v2 = MZ_IS_POS_INFINITY(v2) ? 1.0 : -1.0;
}
#endif
#ifdef ATAN2_DOESNT_WORK_WITH_NAN
if (MZ_IS_NAN(v) || MZ_IS_NAN(v2))
return scheme_nan_object;