1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
diff -Naurd mpfr-2.2.0-p6/sin.c mpfr-2.2.0-p7/sin.c
--- mpfr-2.2.0-p6/sin.c 2005-08-18 17:03:11.000000000 +0000
+++ mpfr-2.2.0-p7/sin.c 2005-12-24 15:17:54.000000000 +0000
@@ -162,10 +162,12 @@
{
/* the absolute error on c is at most 2^(3-m-EXP(c)) */
e = 2 * MPFR_GET_EXP (c) + m - 3;
- if (mpfr_can_round (c, e, GMP_RNDZ, GMP_RNDZ,
+ if (mpfr_can_round (c, e, GMP_RNDN, GMP_RNDZ,
precy + (rnd_mode == GMP_RNDN)))
- /* WARNING: need one more bit for rounding to nearest,
- to be able to get the inexact flag correct */
+ /* WARNING: even if we know c <= sin(x), don't give GMP_RNDZ
+ as 3rd argument to mpfr_can_round, since if c is exactly
+ representable to the target precision (inexact = 0 below),
+ we would have to add one ulp when rounding away from 0. */
break;
/* check for huge cancellation (Near 0) */
@@ -183,14 +185,8 @@
MPFR_ZIV_FREE (loop);
inexact = mpfr_set (y, c, rnd_mode);
-
- /* sin(x) is exact only for x = 0, which was treated apart above;
- nevertheless, we can have inexact = 0 here if the approximation c
- is exactly representable with PREC(y) bits. Since c is an approximation
- towards zero, in that case the inexact flag should have the opposite sign
- as y. */
- if (MPFR_UNLIKELY (inexact == 0))
- inexact = -MPFR_INT_SIGN (y);
+ /* inexact cannot be 0, since this would mean that c was representable
+ within the target precision, but in that case mpfr_can_round will fail */
mpfr_clear (c);
|