This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 2/4] Check n instead of k1 to decide on sign of sin/cos result


On 09/27/2016 01:49 PM, Siddhesh Poyarekar wrote:
> For k1 in 1 and 3, n can only have values of 0 and 2, so checking k1 &
> 2 is equivalent to checking n & 2.  We prefer the latter so that we
> don't use k1 for anything other than selecting the quadrant in
> do_sincos_1, thus dropping it completely.

This is only true of the quadrant shift K is restricted to 0 or 1, which
is true of the code today, but may not be true tomorrow. 

In which case you need `assert (k == 0 || k == 1);` and a comment
about this function only working for a shift of 0 or 1.

OK to checkin if you add the assert and comment.

> 	* sysdeps/ieee754/dbl-64/s_sin.c (do_sincos_1): Check N
> 	instead of K1.
> ---
>  sysdeps/ieee754/dbl-64/s_sin.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
> index d60feb4..ea41a7c 100644
> --- a/sysdeps/ieee754/dbl-64/s_sin.c
> +++ b/sysdeps/ieee754/dbl-64/s_sin.c
> @@ -353,7 +353,7 @@ do_sincos_1 (double a, double da, double x, int4 n, int4 k)
>      case 3:
>        res = do_cos (a, da, &cor);
>        cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps;
> -      retval = ((res == res + cor) ? ((k1 & 2) ? -res : res)
> +      retval = ((res == res + cor) ? ((n & 2) ? -res : res)
>  		: sloww2 (a, da, x, n));
>        break;
>      }
> 

Start with:
(k1 & 2)

Expand in:
k1 = (n + k) & 3
(((n + k) & 3) & 2)

Simplify:
(n + k) & 2

Assume k1 is 1 or 3:
(n + k) & 3 = 1
(n + k) & 3 = 3

Requires the following ranges:
n = 0, k = 1
n = 1, k = 0

n = 0, k = 3
n = 1, k = 2
n = 2, k = 1
n = 3, k = 0


Produces the following result:
n = 0, k = 1, (n + k) & 2 = 0, n & 2 = 0; PASS
n = 1, k = 0, (n + k) & 2 = 0, n & 2 = 0; PASS

n = 0, k = 3, (n + k) & 2 = 2, n & 2 = 0; FAIL
n = 1, k = 2, (n + k) & 2 = 2, n & 2 = 0; FAIL
n = 2, k = 1, (n + k) & 2 = 2, n & 2 = 2; PASS
n = 3, k = 0, (n + k) & 2 = 2, n & 2 = 2; PASS

Thus the substitution you make is invalid for case where K is 2 or 3,
but that's never used in the code.

-- 
Cheers,
Carlos.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]