summaryrefslogtreecommitdiff
path: root/sin_cos.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2007-12-14 14:26:21 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2007-12-14 14:26:21 +0000
commite8b613cf6f6c515e2e70962835150c3ea2949b52 (patch)
tree1dd6e417c96586315155908bb45c675c0da4d0fc /sin_cos.c
parentd78a403075b35233eabf3903bc96395b31ba7148 (diff)
downloadmpfr-e8b613cf6f6c515e2e70962835150c3ea2949b52.tar.gz
simplified MPFR_FAST_COMPUTE_IF_SMALL_INPUT part (in case of overlap)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@5089 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'sin_cos.c')
-rw-r--r--sin_cos.c64
1 files changed, 34 insertions, 30 deletions
diff --git a/sin_cos.c b/sin_cos.c
index e46e3781c..d667711f7 100644
--- a/sin_cos.c
+++ b/sin_cos.c
@@ -74,43 +74,47 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mp_rnd_t rnd_mode)
functions. Moreover, any overflow on m is avoided. */
if (expx < 0)
{
- /* Warning: in case y = x or z = x, and MPFR_FAST_COMPUTE_IF_SMALL_INPUT
- fails, we have to restore the original value of x. */
- mpfr_t t;
- int reuse = y == x || z == x;
-
- if (reuse)
+ /* Warning: in case y = x, and the first call to
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT succeeds but the second fails,
+ we will have clobbered the original value of x.
+ The workaround is to first compute z = cos(x) in that case, since
+ y and z are different. */
+ if (y != x)
+ /* y and x differ, thus we can safely try to compute y first */
{
- mpfr_init2 (t, MPFR_PREC(x));
- mpfr_set (t, x, GMP_RNDN);
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * expx, 2, 0, rnd_mode,
+ { inexy = _inexact;
+ goto small_input; });
+ if (0)
+ {
+ small_input:
+ /* we can go here only if we can round sin(x) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (z, __gmpfr_one, -2 * expx,
+ 1, 0, rnd_mode,
+ { inexz = _inexact;
+ goto end; });
+ }
+
+ /* if we go here, one of the two MPFR_FAST_COMPUTE_IF_SMALL_INPUT
+ calls failed */
}
-
- MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * expx, 2, 0, rnd_mode,
- { inexy = _inexact;
- goto small_input; });
-
- if (0)
+ else /* y and x are the same variable: try to compute z first, which
+ necessarily differs */
{
- small_input:
MPFR_FAST_COMPUTE_IF_SMALL_INPUT (z, __gmpfr_one, -2 * expx,
1, 0, rnd_mode,
{ inexz = _inexact;
- if (reuse)
- mpfr_clear (t);
- goto end; });
+ goto small_input2; });
+ if (0)
+ {
+ small_input2:
+ /* we can go here only if we can round cos(x) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * expx, 2, 0,
+ rnd_mode,
+ { inexy = _inexact;
+ goto end; });
+ }
}
-
- /* if we go here, one of the two MPFR_FAST_COMPUTE_IF_SMALL_INPUT calls
- failed */
- if (reuse)
- {
- /* FIXME: can we use mpfr_swap here and above?
- [VL] How? In any case, I don't think so, since y and/or z
- may be read-only. */
- mpfr_set ((mpfr_ptr) x, t, GMP_RNDN);
- mpfr_clear (t);
- }
-
m += 2 * (-expx);
}