about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2013-09-19 16:45:27 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2013-09-19 16:45:27 +0530
commit6cce25f814400769e77d1d8d1fea0c5882faf0d2 (patch)
treef8b56e5adf0e82062a8c4c325a909574515f188f
parent5eea0404a81a1c6acd45458aede9be2e870d8e5e (diff)
downloadglibc-6cce25f814400769e77d1d8d1fea0c5882faf0d2.tar.gz
glibc-6cce25f814400769e77d1d8d1fea0c5882faf0d2.tar.xz
glibc-6cce25f814400769e77d1d8d1fea0c5882faf0d2.zip
Consolidate sin/cos computation for large inputs
-rw-r--r--ChangeLog5
-rw-r--r--sysdeps/ieee754/dbl-64/s_sin.c83
2 files changed, 41 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index 0591a96f89..3245378c1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2013-09-19  Siddhesh Poyarekar  <siddhesh@redhat.com>
 
+	* sysdeps/ieee754/dbl-64/s_sin.c (reduce_and_compute): New
+	function.
+	(__sin): Use it.
+	(__cos): Likewise.
+
 	* sysdeps/ieee754/dbl-64/s_sin.c (__sin): Remove redundant
 	gotos.
 	(__cos): Likewise.
diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
index 473c0f3f12..93ad8d7619 100644
--- a/sysdeps/ieee754/dbl-64/s_sin.c
+++ b/sysdeps/ieee754/dbl-64/s_sin.c
@@ -93,6 +93,39 @@ static double csloww (double x, double dx, double orig);
 static double csloww1 (double x, double dx, double orig);
 static double csloww2 (double x, double dx, double orig, int n);
 
+/* Reduce range of X and compute sin of a + da.  K is the amount by which to
+   rotate the quadrants.  This allows us to use the same routine to compute cos
+   by simply rotating the quadrants by 1.  */
+static inline double
+__always_inline
+reduce_and_compute (double x, double a, double da, unsigned int k)
+{
+  double retval = 0;
+  unsigned int n = __branred (x, &a, &da);
+  k = (n + k) % 4;
+  switch (k)
+    {
+      case 0:
+	if (a * a < 0.01588)
+	  retval = bsloww (a, da, x, n);
+	else
+	  retval = bsloww1 (a, da, x, n);
+	break;
+      case 2:
+	if (a * a < 0.01588)
+	  retval = bsloww (-a, -da, x, n);
+	else
+	  retval = bsloww1 (-a, -da, x, n);
+	break;
+
+      case 1:
+      case 3:
+	retval = bsloww2 (a, da, x, n);
+	break;
+    }
+  return retval;
+}
+
 /*******************************************************************/
 /* An ultimate sin routine. Given an IEEE double machine number x   */
 /* it computes the correctly rounded (to nearest) value of sin(x)  */
@@ -366,29 +399,7 @@ __sin (double x)
 
 /* -----------------281474976710656 <|x| <2^1024----------------------------*/
   else if (k < 0x7ff00000)
-    {
-      n = __branred (x, &a, &da);
-      switch (n)
-	{
-	case 0:
-	  if (a * a < 0.01588)
-	    retval = bsloww (a, da, x, n);
-	  else
-	    retval = bsloww1 (a, da, x, n);
-	  break;
-	case 2:
-	  if (a * a < 0.01588)
-	    retval = bsloww (-a, -da, x, n);
-	  else
-	    retval = bsloww1 (-a, -da, x, n);
-	  break;
-
-	case 1:
-	case 3:
-	  retval = bsloww2 (a, da, x, n);
-	  break;
-	}
-    }				/*   else  if (k <  0x7ff00000 )    */
+    retval = reduce_and_compute (x, a, da, 0);
 
 /*--------------------- |x| > 2^1024 ----------------------------------*/
   else
@@ -684,31 +695,9 @@ __cos (double x)
 	}
     }				/*   else  if (k <  0x42F00000 )    */
 
+  /* 281474976710656 <|x| <2^1024 */
   else if (k < 0x7ff00000)
-    {				/* 281474976710656 <|x| <2^1024 */
-
-      n = __branred (x, &a, &da);
-      switch (n)
-	{
-	case 1:
-	  if (a * a < 0.01588)
-	    retval = bsloww (-a, -da, x, n);
-	  else
-	    retval = bsloww1 (-a, -da, x, n);
-	  break;
-	case 3:
-	  if (a * a < 0.01588)
-	    retval = bsloww (a, da, x, n);
-	  else
-	    retval = bsloww1 (a, da, x, n);
-	  break;
-
-	case 0:
-	case 2:
-	  retval = bsloww2 (a, da, x, n);
-	  break;
-	}
-    }				/*   else  if (k <  0x7ff00000 )    */
+    retval = reduce_and_compute (x, a, da, 1);
 
   else
     {