about summary refs log tree commit diff
path: root/sysdeps/ieee754/dbl-64/s_sin.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-03-12 00:04:52 +0000
committerUlrich Drepper <drepper@redhat.com>2001-03-12 00:04:52 +0000
commite4d8276142b9c07b23043ef44b0fe8fa7bcc3121 (patch)
treef153a80b6ce0fdd3261ff18a16fd80bd965231c3 /sysdeps/ieee754/dbl-64/s_sin.c
parentd3c8723f6415af59a6ec14fcb918ad0e4d1fb588 (diff)
downloadglibc-e4d8276142b9c07b23043ef44b0fe8fa7bcc3121.tar.gz
glibc-e4d8276142b9c07b23043ef44b0fe8fa7bcc3121.tar.xz
glibc-e4d8276142b9c07b23043ef44b0fe8fa7bcc3121.zip
Update.
2001-03-11  Ulrich Drepper  <drepper@redhat.com>

	Last-bit accurate math library implementation by IBM Haifa.
	Contributed by Abraham Ziv <ziv@il.ibm.com>, Moshe Olshansky
	<olshansk@il.ibm.com>, Ealan Henis <ealan@il.ibm.com>, and
	Anna Reitman <reitman@il.ibm.com>.
	* math/Makefile (dbl-only-routines): New variable.
	(libm-routines): Add $(dbl-only-routines).
	* sysdeps/ieee754/dbl-64/e_acos.c: Empty, definition is in e_asin.c.
	* sysdeps/ieee754/dbl-64/e_asin.c: Replaced with accurate asin
	implementation.
	* sysdeps/ieee754/dbl-64/e_atan2.c: Replaced with accurate atan2
	implementation.
	* sysdeps/ieee754/dbl-64/e_exp.c: Replaced with accurate exp
	implementation.
	* sysdeps/ieee754/dbl-64/e_lgamma_r.c: Don't use __kernel_sin and
	__kernel_cos.
	* sysdeps/ieee754/dbl-64/e_log.c: Replaced with accurate log
	implementation.
	* sysdeps/ieee754/dbl-64/e_remainder.c: Replaced with accurate
	remainder implementation.
	* sysdeps/ieee754/dbl-64/e_pow.c: Replaced with accurate pow
	implementation.
	* sysdeps/ieee754/dbl-64/e_sqrt.c: Replaced with accurate sqrt
	implementation.
	* sysdeps/ieee754/dbl-64/k_cos.c: Empty, definition is in s_sin.c.
	* sysdeps/ieee754/dbl-64/k_sin.c: Empty, definition is in s_sin.c.
	* sysdeps/ieee754/dbl-64/s_atan.c: Replaced with accurate atan
	implementation.
	* sysdeps/ieee754/dbl-64/s_cos.c: Empty, definition is in s_sin.c.
	* sysdeps/ieee754/dbl-64/s_sin.c: Replaced with accurate sin/cos
	implementation.
	* sysdeps/ieee754/dbl-64/s_sincos.c: Rewritten to not use __kernel_sin
	and __kernel_cos.
	* sysdeps/ieee754/dbl-64/s_tan.c: Replaced with accurate tan
	implementation.
	* sysdeps/ieee754/dbl-64/Dist: Add new non-code files.
	* sysdeps/ieee754/dbl-64/MathLib.h: New file.
	* sysdeps/ieee754/dbl-64/asincos.tbl: New file.
	* sysdeps/ieee754/dbl-64/atnat.h: New file.
	* sysdeps/ieee754/dbl-64/atnat2.h: New file.
	* sysdeps/ieee754/dbl-64/branred.c: New file.
	* sysdeps/ieee754/dbl-64/branred.h: New file.
	* sysdeps/ieee754/dbl-64/dla.h: New file.
	* sysdeps/ieee754/dbl-64/doasin.c: New file.
	* sysdeps/ieee754/dbl-64/doasin.h: New file.
	* sysdeps/ieee754/dbl-64/dosincos.c: New file.
	* sysdeps/ieee754/dbl-64/dosincos.h: New file.
	* sysdeps/ieee754/dbl-64/endian.h: New file.
	* sysdeps/ieee754/dbl-64/halfulp.c: New file.
	* sysdeps/ieee754/dbl-64/mpa.c: New file.
	* sysdeps/ieee754/dbl-64/mpa.h: New file.
	* sysdeps/ieee754/dbl-64/mpa2.h: New file.
	* sysdeps/ieee754/dbl-64/mpatan.c: New file.
	* sysdeps/ieee754/dbl-64/mpatan.h: New file.
	* sysdeps/ieee754/dbl-64/mpatan2.c: New file.
	* sysdeps/ieee754/dbl-64/mpexp.c: New file.
	* sysdeps/ieee754/dbl-64/mpexp.h: New file.
	* sysdeps/ieee754/dbl-64/mplog.c: New file.
	* sysdeps/ieee754/dbl-64/mplog.h: New file.
	* sysdeps/ieee754/dbl-64/mpsqrt.c: New file.
	* sysdeps/ieee754/dbl-64/mpsqrt.h: New file.
	* sysdeps/ieee754/dbl-64/mptan.c: New file.
	* sysdeps/ieee754/dbl-64/mydefs.h: New file.
	* sysdeps/ieee754/dbl-64/powtwo.tbl: New file.
	* sysdeps/ieee754/dbl-64/root.tbl: New file.
	* sysdeps/ieee754/dbl-64/sincos.tbl: New file.
	* sysdeps/ieee754/dbl-64/sincos32.c: New file.
	* sysdeps/ieee754/dbl-64/sincos32.h: New file.
	* sysdeps/ieee754/dbl-64/slowexp.c: New file.
	* sysdeps/ieee754/dbl-64/slowpow.c: New file.
	* sysdeps/ieee754/dbl-64/uasncs.h: New file.
	* sysdeps/ieee754/dbl-64/uatan.tbl: New file.
	* sysdeps/ieee754/dbl-64/uexp.h: New file.
	* sysdeps/ieee754/dbl-64/uexp.tbl: New file.
	* sysdeps/ieee754/dbl-64/ulog.h: New file.
	* sysdeps/ieee754/dbl-64/ulog.tbl: New file.
	* sysdeps/ieee754/dbl-64/upow.h: New file.
	* sysdeps/ieee754/dbl-64/upow.tbl: New file.
	* sysdeps/ieee754/dbl-64/urem.h: New file.
	* sysdeps/ieee754/dbl-64/uroot.h: New file.
	* sysdeps/ieee754/dbl-64/usncs.h: New file.
	* sysdeps/ieee754/dbl-64/utan.h: New file.
	* sysdeps/ieee754/dbl-64/utan.tbl: New file.
	* sysdeps/i386/fpu/branred.c: New file.
	* sysdeps/i386/fpu/doasin.c: New file.
	* sysdeps/i386/fpu/dosincos.c: New file.
	* sysdeps/i386/fpu/halfulp.c: New file.
	* sysdeps/i386/fpu/mpa.c: New file.
	* sysdeps/i386/fpu/mpatan.c: New file.
	* sysdeps/i386/fpu/mpatan2.c: New file.
	* sysdeps/i386/fpu/mpexp.c: New file.
	* sysdeps/i386/fpu/mplog.c: New file.
	* sysdeps/i386/fpu/mpsqrt.c: New file.
	* sysdeps/i386/fpu/mptan.c: New file.
	* sysdeps/i386/fpu/sincos32.c: New file.
	* sysdeps/i386/fpu/slowexp.c: New file.
	* sysdeps/i386/fpu/slowpow.c: New file.
	* sysdeps/ia64/fpu/branred.c: New file.
	* sysdeps/ia64/fpu/doasin.c: New file.
	* sysdeps/ia64/fpu/dosincos.c: New file.
	* sysdeps/ia64/fpu/halfulp.c: New file.
	* sysdeps/ia64/fpu/mpa.c: New file.
	* sysdeps/ia64/fpu/mpatan.c: New file.
	* sysdeps/ia64/fpu/mpatan2.c: New file.
	* sysdeps/ia64/fpu/mpexp.c: New file.
	* sysdeps/ia64/fpu/mplog.c: New file.
	* sysdeps/ia64/fpu/mpsqrt.c: New file.
	* sysdeps/ia64/fpu/mptan.c: New file.
	* sysdeps/ia64/fpu/sincos32.c: New file.
	* sysdeps/ia64/fpu/slowexp.c: New file.
	* sysdeps/ia64/fpu/slowpow.c: New file.
	* sysdeps/m68k/fpu/branred.c: New file.
	* sysdeps/m68k/fpu/doasin.c: New file.
	* sysdeps/m68k/fpu/dosincos.c: New file.
	* sysdeps/m68k/fpu/halfulp.c: New file.
	* sysdeps/m68k/fpu/mpa.c: New file.
	* sysdeps/m68k/fpu/mpatan.c: New file.
	* sysdeps/m68k/fpu/mpatan2.c: New file.
	* sysdeps/m68k/fpu/mpexp.c: New file.
	* sysdeps/m68k/fpu/mplog.c: New file.
	* sysdeps/m68k/fpu/mpsqrt.c: New file.
	* sysdeps/m68k/fpu/mptan.c: New file.
	* sysdeps/m68k/fpu/sincos32.c: New file.
	* sysdeps/m68k/fpu/slowexp.c: New file.
	* sysdeps/m68k/fpu/slowpow.c: New file.

	* iconvdata/gconv-modules: Add a number of alias, mostly for IBM
	codepages.
Diffstat (limited to 'sysdeps/ieee754/dbl-64/s_sin.c')
-rw-r--r--sysdeps/ieee754/dbl-64/s_sin.c1178
1 files changed, 1102 insertions, 76 deletions
diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
index 376c69ed00..b40c47f389 100644
--- a/sysdeps/ieee754/dbl-64/s_sin.c
+++ b/sysdeps/ieee754/dbl-64/s_sin.c
@@ -1,87 +1,1113 @@
-/* @(#)s_sin.c 5.1 93/09/24 */
 /*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * IBM Accurate Mathematical Library
+ * Copyright (c) International Business Machines Corp., 2001
  *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: s_sin.c,v 1.7 1995/05/10 20:48:15 jtc Exp $";
-#endif
-
-/* sin(x)
- * Return sine function of x.
- *
- * kernel function:
- *	__kernel_sin		... sine function on [-pi/4,pi/4]
- *	__kernel_cos		... cose function on [-pi/4,pi/4]
- *	__ieee754_rem_pio2	... argument reduction routine
- *
- * Method.
- *      Let S,C and T denote the sin, cos and tan respectively on
- *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
- *	in [-pi/4 , +pi/4], and let n = k mod 4.
- *	We have
- *
- *          n        sin(x)      cos(x)        tan(x)
- *     ----------------------------------------------------------
- *	    0	       S	   C		 T
- *	    1	       C	  -S		-1/T
- *	    2	      -S	  -C		 T
- *	    3	      -C	   S		-1/T
- *     ----------------------------------------------------------
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- * Special cases:
- *      Let trig be any of sin, cos, or tan.
- *      trig(+-INF)  is NaN, with signals;
- *      trig(NaN)    is that NaN;
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- * Accuracy:
- *	TRIG(x) returns trig(x) nearly rounded
+ * You should have received a copy of the GNU  Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
+/****************************************************************************/
+/*                                                                          */
+/* MODULE_NAME:usncs.c                                                      */
+/*                                                                          */
+/* FUNCTIONS: usin                                                          */
+/*            ucos                                                          */
+/*            slow                                                          */
+/*            slow1                                                         */
+/*            slow2                                                         */
+/*            sloww                                                         */
+/*            sloww1                                                        */
+/*            sloww2                                                        */
+/*            bsloww                                                        */
+/*            bsloww1                                                       */
+/*            bsloww2                                                       */
+/*            cslow2                                                        */
+/*            csloww                                                        */
+/*            csloww1                                                       */
+/*            csloww2                                                       */
+/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h  usncs.h                     */
+/*               branred.c sincos32.c dosincos.c mpa.c                      */
+/*               sincos.tbl                                                 */
+/*                                                                          */
+/* An ultimate sin and  routine. Given an IEEE double machine number x       */
+/* it computes the correctly rounded (to nearest) value of sin(x) or cos(x) */
+/* Assumption: Machine arithmetic operations are performed in               */
+/* round to nearest mode of IEEE 754 standard.                              */
+/*                                                                          */
+/****************************************************************************/
 
-#include "math.h"
-#include "math_private.h"
 
-#ifdef __STDC__
-	double __sin(double x)
-#else
-	double __sin(x)
-	double x;
-#endif
-{
-	double y[2],z=0.0;
-	int32_t n, ix;
-
-    /* High word of x. */
-	GET_HIGH_WORD(ix,x);
-
-    /* |x| ~< pi/4 */
-	ix &= 0x7fffffff;
-	if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
-
-    /* sin(Inf or NaN) is NaN */
-	else if (ix>=0x7ff00000) return x-x;
-
-    /* argument reduction needed */
-	else {
-	    n = __ieee754_rem_pio2(x,y);
-	    switch(n&3) {
-		case 0: return  __kernel_sin(y[0],y[1],1);
-		case 1: return  __kernel_cos(y[0],y[1]);
-		case 2: return -__kernel_sin(y[0],y[1],1);
-		default:
-			return -__kernel_cos(y[0],y[1]);
+#include "endian.h"
+#include "mydefs.h"
+#include "usncs.h"
+#include "MathLib.h"
+#include "sincos.tbl"
+
+static const double
+          sn3 = -1.66666666666664880952546298448555E-01,
+          sn5 =  8.33333214285722277379541354343671E-03,
+          cs2 =  4.99999999999999999999950396842453E-01,
+          cs4 = -4.16666666666664434524222570944589E-02,
+          cs6 =  1.38888874007937613028114285595617E-03;
+
+void dubsin(double x, double dx, double w[]);
+void docos(double x, double dx, double w[]);
+double mpsin(double x, double dx);
+double mpcos(double x, double dx);
+double mpsin1(double x);
+double mpcos1(double x);
+static double slow(double x);
+static double slow1(double x);
+static double slow2(double x);
+static double sloww(double x, double dx, double orig);
+static double sloww1(double x, double dx, double orig);
+static double sloww2(double x, double dx, double orig, int n);
+static double bsloww(double x, double dx, double orig, int n);
+static double bsloww1(double x, double dx, double orig, int n);
+static double bsloww2(double x, double dx, double orig, int n);
+int branred(double x, double *a, double *aa);
+static double cslow2(double x);
+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);
+/*******************************************************************/
+/* An ultimate sin routine. Given an IEEE double machine number x   */
+/* it computes the correctly rounded (to nearest) value of sin(x)  */
+/*******************************************************************/
+double sin(double x){
+	double xx,res,t,cor,y,w[2],s,c,sn,ssn,cs,ccs,xn,a,da,db,eps,xn1,xn2;
+	mynumber u,v;
+	int4 k,m,n,nn;
+
+	u.x = x;
+	m = u.i[HIGH_HALF];
+	k = 0x7fffffff&m;              /* no sign           */
+	if (k < 0x3e500000)            /* if x->0 =>sin(x)=x */
+	 return x;
+ /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/
+	else  if (k < 0x3fd00000){
+	  xx = x*x;
+	  /*Taylor series */
+	  t = ((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*(xx*x);
+	  res = x+t;
+	  cor = (x-res)+t;
+	  return (res == res + 1.07*cor)? res : slow(x);
+	}    /*  else  if (k < 0x3fd00000)    */
+/*---------------------------- 0.25<|x|< 0.855469---------------------- */
+	else if (k < 0x3feb6000)  {
+	  u.x=(m>0)?big.x+x:big.x-x;
+	  y=(m>0)?x-(u.x-big.x):x+(u.x-big.x);
+	  xx=y*y;
+	  s = y + y*xx*(sn3 +xx*sn5);
+	  c = xx*(cs2 +xx*(cs4 + xx*cs6));
+	  k=u.i[LOW_HALF]<<2;
+	  sn=(m>0)?sincos.x[k]:-sincos.x[k];
+	  ssn=(m>0)?sincos.x[k+1]:-sincos.x[k+1];
+	  cs=sincos.x[k+2];
+	  ccs=sincos.x[k+3];
+	  cor=(ssn+s*ccs-sn*c)+cs*s;
+	  res=sn+cor;
+	  cor=(sn-res)+cor;
+	  return (res==res+1.025*cor)? res : slow1(x);
+	}    /*   else  if (k < 0x3feb6000)    */
+
+/*----------------------- 0.855469  <|x|<2.426265  ----------------------*/
+	else if (k <  0x400368fd ) {
+
+	  y = (m>0)? hp0.x-x:hp0.x+x;
+	  if (y>=0) {
+	    u.x = big.x+y;
+	    y = (y-(u.x-big.x))+hp1.x;
+	  }
+	  else {
+	    u.x = big.x-y;
+	    y = (-hp1.x) - (y+(u.x-big.x));
+	  }
+	  xx=y*y;
+	  s = y + y*xx*(sn3 +xx*sn5);
+	  c = xx*(cs2 +xx*(cs4 + xx*cs6));
+	  k=u.i[LOW_HALF]<<2;
+	  sn=sincos.x[k];
+	  ssn=sincos.x[k+1];
+	  cs=sincos.x[k+2];
+	  ccs=sincos.x[k+3];
+	  cor=(ccs-s*ssn-cs*c)-sn*s;
+	  res=cs+cor;
+	  cor=(cs-res)+cor;
+	  return (res==res+1.020*cor)? ((m>0)?res:-res) : slow2(x);
+	} /*   else  if (k < 0x400368fd)    */
+
+/*-------------------------- 2.426265<|x|< 105414350 ----------------------*/
+	else if (k < 0x419921FB ) {
+	  t = (x*hpinv.x + toint.x);
+	  xn = t - toint.x;
+	  v.x = t;
+	  y = (x - xn*mp1.x) - xn*mp2.x;
+	  n =v.i[LOW_HALF]&3;
+	  da = xn*mp3.x;
+	  a=y-da;
+	  da = (y-a)-da;
+	  eps = ABS(x)*1.2e-30;
+
+	  switch (n) { /* quarter of unit circle */
+	  case 0:
+	  case 2:
+	    xx = a*a;
+	    if (n) {a=-a;da=-da;}
+	    if (xx < 0.01588) {
+                      /*Taylor series */
+	      t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
+	      res = a+t;
+	      cor = (a-res)+t;
+	      cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+	      return (res == res + cor)? res : sloww(a,da,x);
 	    }
-	}
+	    else  {
+	      if (a>0)
+		{m=1;t=a;db=da;}
+	      else
+		{m=0;t=-a;db=-da;}
+	      u.x=big.x+t;
+	      y=t-(u.x-big.x);
+	      xx=y*y;
+	      s = y + (db+y*xx*(sn3 +xx*sn5));
+	      c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
+	      k=u.i[LOW_HALF]<<2;
+	      sn=sincos.x[k];
+	      ssn=sincos.x[k+1];
+	      cs=sincos.x[k+2];
+	      ccs=sincos.x[k+3];
+	      cor=(ssn+s*ccs-sn*c)+cs*s;
+	      res=sn+cor;
+	      cor=(sn-res)+cor;
+	      cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+	      return (res==res+cor)? ((m)?res:-res) : sloww1(a,da,x);
+	    }
+	    break;
+
+	  case 1:
+	  case 3:
+	    if (a<0)
+	      {a=-a;da=-da;}
+	    u.x=big.x+a;
+	    y=a-(u.x-big.x)+da;
+	    xx=y*y;
+	    k=u.i[LOW_HALF]<<2;
+	    sn=sincos.x[k];
+	    ssn=sincos.x[k+1];
+	    cs=sincos.x[k+2];
+	    ccs=sincos.x[k+3];
+	    s = y + y*xx*(sn3 +xx*sn5);
+	    c = xx*(cs2 +xx*(cs4 + xx*cs6));
+	    cor=(ccs-s*ssn-cs*c)-sn*s;
+	    res=cs+cor;
+	    cor=(cs-res)+cor;
+	    cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+	    return (res==res+cor)? ((n&2)?-res:res) : sloww2(a,da,x,n);
+
+	    break;
+
+	  }
+
+	}    /*   else  if (k <  0x419921FB )    */
+
+/*---------------------105414350 <|x|< 281474976710656 --------------------*/
+	else if (k < 0x42F00000 ) {
+	  t = (x*hpinv.x + toint.x);
+	  xn = t - toint.x;
+	  v.x = t;
+	  xn1 = (xn+8.0e22)-8.0e22;
+	  xn2 = xn - xn1;
+	  y = ((((x - xn1*mp1.x) - xn1*mp2.x)-xn2*mp1.x)-xn2*mp2.x);
+	  n =v.i[LOW_HALF]&3;
+	  da = xn1*pp3.x;
+	  t=y-da;
+	  da = (y-t)-da;
+	  da = (da - xn2*pp3.x) -xn*pp4.x;
+	  a = t+da;
+	  da = (t-a)+da;
+	  eps = 1.0e-24;
+
+	  switch (n) {
+	  case 0:
+	  case 2:
+	    xx = a*a;
+	    if (n) {a=-a;da=-da;}
+	    if (xx < 0.01588) {
+              /* Taylor series */
+	      t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
+	      res = a+t;
+	      cor = (a-res)+t;
+	      cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+	      return (res == res + cor)? res : bsloww(a,da,x,n);
+	    }
+	    else  {
+	      if (a>0) {m=1;t=a;db=da;}
+	      else {m=0;t=-a;db=-da;}
+	      u.x=big.x+t;
+	      y=t-(u.x-big.x);
+	      xx=y*y;
+	      s = y + (db+y*xx*(sn3 +xx*sn5));
+	      c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
+	      k=u.i[LOW_HALF]<<2;
+	      sn=sincos.x[k];
+	      ssn=sincos.x[k+1];
+	      cs=sincos.x[k+2];
+	      ccs=sincos.x[k+3];
+	      cor=(ssn+s*ccs-sn*c)+cs*s;
+	      res=sn+cor;
+	      cor=(sn-res)+cor;
+	      cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+	      return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
+		   }
+	    break;
+
+	  case 1:
+	  case 3:
+	    if (a<0)
+	      {a=-a;da=-da;}
+	    u.x=big.x+a;
+	    y=a-(u.x-big.x)+da;
+	    xx=y*y;
+	    k=u.i[LOW_HALF]<<2;
+	    sn=sincos.x[k];
+	    ssn=sincos.x[k+1];
+	    cs=sincos.x[k+2];
+	    ccs=sincos.x[k+3];
+	    s = y + y*xx*(sn3 +xx*sn5);
+	    c = xx*(cs2 +xx*(cs4 + xx*cs6));
+	    cor=(ccs-s*ssn-cs*c)-sn*s;
+	    res=cs+cor;
+	    cor=(cs-res)+cor;
+	    cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+	    return (res==res+cor)? ((n&2)?-res:res) : bsloww2(a,da,x,n);
+
+	    break;
+
+	  }
+
+	}    /*   else  if (k <  0x42F00000 )   */
+
+/* -----------------281474976710656 <|x| <2^1024----------------------------*/
+	else if (k < 0x7ff00000) {
+
+	  n = branred(x,&a,&da);
+	  switch (n) {
+	  case 0:
+	    if (a*a < 0.01588) return bsloww(a,da,x,n);
+	    else return bsloww1(a,da,x,n);
+	    break;
+	  case 2:
+	    if (a*a < 0.01588) return bsloww(-a,-da,x,n);
+	    else return bsloww1(-a,-da,x,n);
+	    break;
+
+	  case 1:
+	  case 3:
+	    return  bsloww2(a,da,x,n);
+	    break;
+	  }
+
+	}    /*   else  if (k <  0x7ff00000 )    */
+
+/*--------------------- |x| > 2^1024 ----------------------------------*/
+	else return NAN.x;
+	return 0;         /* unreachable */
+}
+
+
+/*******************************************************************/
+/* An ultimate cos routine. Given an IEEE double machine number x   */
+/* it computes the correctly rounded (to nearest) value of cos(x)  */
+/*******************************************************************/
+
+double cos(double x)
+{
+  double y,xx,res,t,cor,s,c,sn,ssn,cs,ccs,xn,a,da,db,eps,xn1,xn2;
+  mynumber u,v;
+  int4 k,m,n;
+
+  u.x = x;
+  m = u.i[HIGH_HALF];
+  k = 0x7fffffff&m;
+
+  if (k < 0x3e400000 ) return 1.0; /* |x|<2^-27 => cos(x)=1 */
+
+  else if (k < 0x3feb6000 ) {/* 2^-27 < |x| < 0.855469 */
+    y=ABS(x);
+    u.x = big.x+y;
+    y = y-(u.x-big.x);
+    xx=y*y;
+    s = y + y*xx*(sn3 +xx*sn5);
+    c = xx*(cs2 +xx*(cs4 + xx*cs6));
+    k=u.i[LOW_HALF]<<2;
+    sn=sincos.x[k];
+    ssn=sincos.x[k+1];
+    cs=sincos.x[k+2];
+    ccs=sincos.x[k+3];
+    cor=(ccs-s*ssn-cs*c)-sn*s;
+    res=cs+cor;
+    cor=(cs-res)+cor;
+    return (res==res+1.020*cor)? res : cslow2(x);
+
+}    /*   else  if (k < 0x3feb6000)    */
+
+  else if (k <  0x400368fd ) {/* 0.855469  <|x|<2.426265  */;
+    y=hp0.x-ABS(x);
+    a=y+hp1.x;
+    da=(y-a)+hp1.x;
+    xx=a*a;
+    if (xx < 0.01588) {
+      t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
+      res = a+t;
+      cor = (a-res)+t;
+      cor = (cor>0)? 1.02*cor+1.0e-31 : 1.02*cor -1.0e-31;
+      return (res == res + cor)? res : csloww(a,da,x);
+    }
+    else  {
+      if (a>0) {m=1;t=a;db=da;}
+      else {m=0;t=-a;db=-da;}
+      u.x=big.x+t;
+      y=t-(u.x-big.x);
+      xx=y*y;
+      s = y + (db+y*xx*(sn3 +xx*sn5));
+      c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
+      k=u.i[LOW_HALF]<<2;
+      sn=sincos.x[k];
+      ssn=sincos.x[k+1];
+      cs=sincos.x[k+2];
+      ccs=sincos.x[k+3];
+      cor=(ssn+s*ccs-sn*c)+cs*s;
+      res=sn+cor;
+      cor=(sn-res)+cor;
+      cor = (cor>0)? 1.035*cor+1.0e-31 : 1.035*cor-1.0e-31;
+      return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
 }
-weak_alias (__sin, sin)
+
+}    /*   else  if (k < 0x400368fd)    */
+
+
+  else if (k < 0x419921FB ) {/* 2.426265<|x|< 105414350 */
+    t = (x*hpinv.x + toint.x);
+    xn = t - toint.x;
+    v.x = t;
+    y = (x - xn*mp1.x) - xn*mp2.x;
+    n =v.i[LOW_HALF]&3;
+    da = xn*mp3.x;
+    a=y-da;
+    da = (y-a)-da;
+    eps = ABS(x)*1.2e-30;
+
+    switch (n) {
+    case 1:
+    case 3:
+      xx = a*a;
+      if (n == 1) {a=-a;da=-da;}
+      if (xx < 0.01588) {
+	t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
+	res = a+t;
+	cor = (a-res)+t;
+	cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+	return (res == res + cor)? res : csloww(a,da,x);
+      }
+      else  {
+	if (a>0) {m=1;t=a;db=da;}
+	else {m=0;t=-a;db=-da;}
+	u.x=big.x+t;
+	y=t-(u.x-big.x);
+	xx=y*y;
+	s = y + (db+y*xx*(sn3 +xx*sn5));
+	c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
+	k=u.i[LOW_HALF]<<2;
+	sn=sincos.x[k];
+	ssn=sincos.x[k+1];
+	cs=sincos.x[k+2];
+	ccs=sincos.x[k+3];
+	cor=(ssn+s*ccs-sn*c)+cs*s;
+	res=sn+cor;
+	cor=(sn-res)+cor;
+	cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+	return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
+      }
+      break;
+
+  case 0:
+    case 2:
+      if (a<0) {a=-a;da=-da;}
+      u.x=big.x+a;
+      y=a-(u.x-big.x)+da;
+      xx=y*y;
+      k=u.i[LOW_HALF]<<2;
+      sn=sincos.x[k];
+      ssn=sincos.x[k+1];
+      cs=sincos.x[k+2];
+      ccs=sincos.x[k+3];
+      s = y + y*xx*(sn3 +xx*sn5);
+      c = xx*(cs2 +xx*(cs4 + xx*cs6));
+      cor=(ccs-s*ssn-cs*c)-sn*s;
+      res=cs+cor;
+      cor=(cs-res)+cor;
+      cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+      return (res==res+cor)? ((n)?-res:res) : csloww2(a,da,x,n);
+
+           break;
+
+    }
+
+  }    /*   else  if (k <  0x419921FB )    */
+
+
+  else if (k < 0x42F00000 ) {
+    t = (x*hpinv.x + toint.x);
+    xn = t - toint.x;
+    v.x = t;
+    xn1 = (xn+8.0e22)-8.0e22;
+    xn2 = xn - xn1;
+    y = ((((x - xn1*mp1.x) - xn1*mp2.x)-xn2*mp1.x)-xn2*mp2.x);
+    n =v.i[LOW_HALF]&3;
+    da = xn1*pp3.x;
+    t=y-da;
+    da = (y-t)-da;
+    da = (da - xn2*pp3.x) -xn*pp4.x;
+    a = t+da;
+    da = (t-a)+da;
+    eps = 1.0e-24;
+
+    switch (n) {
+    case 1:
+    case 3:
+      xx = a*a;
+      if (n==1) {a=-a;da=-da;}
+      if (xx < 0.01588) {
+	t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
+	res = a+t;
+	cor = (a-res)+t;
+	cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+	return (res == res + cor)? res : bsloww(a,da,x,n);
+      }
+      else  {
+	if (a>0) {m=1;t=a;db=da;}
+	else {m=0;t=-a;db=-da;}
+	u.x=big.x+t;
+	y=t-(u.x-big.x);
+	xx=y*y;
+	s = y + (db+y*xx*(sn3 +xx*sn5));
+	c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
+	k=u.i[LOW_HALF]<<2;
+	sn=sincos.x[k];
+	ssn=sincos.x[k+1];
+	cs=sincos.x[k+2];
+	ccs=sincos.x[k+3];
+	cor=(ssn+s*ccs-sn*c)+cs*s;
+	res=sn+cor;
+	cor=(sn-res)+cor;
+	cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+	return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
+      }
+      break;
+
+    case 0:
+    case 2:
+      if (a<0) {a=-a;da=-da;}
+      u.x=big.x+a;
+      y=a-(u.x-big.x)+da;
+      xx=y*y;
+      k=u.i[LOW_HALF]<<2;
+      sn=sincos.x[k];
+      ssn=sincos.x[k+1];
+      cs=sincos.x[k+2];
+      ccs=sincos.x[k+3];
+      s = y + y*xx*(sn3 +xx*sn5);
+      c = xx*(cs2 +xx*(cs4 + xx*cs6));
+      cor=(ccs-s*ssn-cs*c)-sn*s;
+      res=cs+cor;
+      cor=(cs-res)+cor;
+      cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+      return (res==res+cor)? ((n)?-res:res) : bsloww2(a,da,x,n);
+      break;
+
+    }
+
+  }    /*   else  if (k <  0x42F00000 )    */
+
+  else if (k < 0x7ff00000) {/* 281474976710656 <|x| <2^1024 */
+
+    n = branred(x,&a,&da);
+    switch (n) {
+    case 1:
+      if (a*a < 0.01588) return bsloww(-a,-da,x,n);
+      else return bsloww1(-a,-da,x,n);
+      break;
+		case 3:
+		  if (a*a < 0.01588) return bsloww(a,da,x,n);
+		  else return bsloww1(a,da,x,n);
+		  break;
+
+    case 0:
+    case 2:
+      return  bsloww2(a,da,x,n);
+      break;
+    }
+
+  }    /*   else  if (k <  0x7ff00000 )    */
+
+
+
+
+  else return NAN.x; /* |x| > 2^1024 */
+  return 0;
+
+}
+
+/************************************************************************/
+/*  Routine compute sin(x) for  2^-26 < |x|< 0.25 by  Taylor with more   */
+/* precision  and if still doesn't accurate enough by mpsin   or dubsin */
+/************************************************************************/
+
+static double slow(double x) {
+static const double th2_36 = 206158430208.0;   /*    1.5*2**37   */
+ double y,x1,x2,xx,r,t,res,cor,w[2];
+ x1=(x+th2_36)-th2_36;
+ y = aa.x*x1*x1*x1;
+ r=x+y;
+ x2=x-x1;
+ xx=x*x;
+ t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + bb.x)*xx + 3.0*aa.x*x1*x2)*x +aa.x*x2*x2*x2;
+ t=((x-r)+y)+t;
+ res=r+t;
+ cor = (r-res)+t;
+ if (res == res + 1.0007*cor) return res;
+ else {
+   dubsin(ABS(x),0,w);
+   if (w[0] == w[0]+1.000000001*w[1]) return (x>0)?w[0]:-w[0];
+   else return (x>0)?mpsin(x,0):-mpsin(-x,0);
+ }
+}
+/*******************************************************************************/
+/* Routine compute sin(x) for   0.25<|x|< 0.855469 by  sincos.tbl   and Taylor */
+/* and if result still doesn't accurate enough by mpsin   or dubsin            */
+/*******************************************************************************/
+
+static double slow1(double x) {
+  mynumber u;
+  double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,c1,c2,xx,cor,res;
+  static const double t22 = 6291456.0;
+  int4 k;
+  y=ABS(x);
+  u.x=big.x+y;
+  y=y-(u.x-big.x);
+  xx=y*y;
+  s = y*xx*(sn3 +xx*sn5);
+  c = xx*(cs2 +xx*(cs4 + xx*cs6));
+  k=u.i[LOW_HALF]<<2;
+  sn=sincos.x[k];          /* Data          */
+  ssn=sincos.x[k+1];       /*  from         */
+  cs=sincos.x[k+2];        /*   tables      */
+  ccs=sincos.x[k+3];       /*    sincos.tbl */
+  y1 = (y+t22)-t22;
+  y2 = y - y1;
+  c1 = (cs+t22)-t22;
+  c2=(cs-c1)+ccs;
+  cor=(ssn+s*ccs+cs*s+c2*y+c1*y2)-sn*c;
+  y=sn+c1*y1;
+  cor = cor+((sn-y)+c1*y1);
+  res=y+cor;
+  cor=(y-res)+cor;
+  if (res == res+1.0005*cor) return (x>0)?res:-res;
+  else {
+    dubsin(ABS(x),0,w);
+    if (w[0] == w[0]+1.000000005*w[1]) return (x>0)?w[0]:-w[0];
+    else return (x>0)?mpsin(x,0):-mpsin(-x,0);
+  }
+}
+/**************************************************************************/
+/*  Routine compute sin(x) for   0.855469  <|x|<2.426265  by  sincos.tbl  */
+/* and if result still doesn't accurate enough by mpsin   or dubsin       */
+/**************************************************************************/
+static double slow2(double x) {
+  mynumber u;
+  double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,e1,e2,xx,cor,res,del;
+  static const double t22 = 6291456.0;
+  int4 k;
+  y=ABS(x);
+  y = hp0.x-y;
+  if (y>=0) {
+    u.x = big.x+y;
+    y = y-(u.x-big.x);
+    del = hp1.x;
+  }
+  else {
+    u.x = big.x-y;
+    y = -(y+(u.x-big.x));
+    del = -hp1.x;
+  }
+  xx=y*y;
+  s = y*xx*(sn3 +xx*sn5);
+  c = y*del+xx*(cs2 +xx*(cs4 + xx*cs6));
+  k=u.i[LOW_HALF]<<2;
+  sn=sincos.x[k];
+  ssn=sincos.x[k+1];
+  cs=sincos.x[k+2];
+  ccs=sincos.x[k+3];
+  y1 = (y+t22)-t22;
+  y2 = (y - y1)+del;
+  e1 = (sn+t22)-t22;
+  e2=(sn-e1)+ssn;
+  cor=(ccs-cs*c-e1*y2-e2*y)-sn*s;
+  y=cs-e1*y1;
+  cor = cor+((cs-y)-e1*y1);
+  res=y+cor;
+  cor=(y-res)+cor;
+  if (res == res+1.0005*cor) return (x>0)?res:-res;
+  else {
+    y=ABS(x)-hp0.x;
+    y1=y-hp1.x;
+    y2=(y-y1)-hp1.x;
+    docos(y1,y2,w);
+    if (w[0] == w[0]+1.000000005*w[1]) return (x>0)?w[0]:-w[0];
+    else return (x>0)?mpsin(x,0):-mpsin(-x,0);
+  }
+}
+/***************************************************************************/
+/*  Routine compute sin(x+dx) (Double-Length number) where x is small enough*/
+/* to use Taylor series around zero and   (x+dx)                            */
+/* in first or third quarter of unit circle.Routine receive also            */
+/* (right argument) the  original   value of x for computing error of      */
+/* result.And if result not accurate enough routine calls mpsin1 or dubsin */
+/***************************************************************************/
+
+static double sloww(double x,double dx, double orig) {
+  static const double th2_36 = 206158430208.0;   /*    1.5*2**37   */
+  double y,x1,x2,xx,r,t,res,cor,w[2],a,da,xn;
+  union {int4 i[2]; double x;} v;
+  int4 n;
+  x1=(x+th2_36)-th2_36;
+  y = aa.x*x1*x1*x1;
+  r=x+y;
+  x2=(x-x1)+dx;
+  xx=x*x;
+  t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + bb.x)*xx + 3.0*aa.x*x1*x2)*x +aa.x*x2*x2*x2+dx;
+  t=((x-r)+y)+t;
+  res=r+t;
+  cor = (r-res)+t;
+  cor = (cor>0)? 1.0005*cor+ABS(orig)*3.1e-30 : 1.0005*cor-ABS(orig)*3.1e-30;
+  if (res == res + cor) return res;
+  else {
+    (x>0)? dubsin(x,dx,w) : dubsin(-x,-dx,w);
+    cor = (w[1]>0)? 1.000000001*w[1] + ABS(orig)*1.1e-30 : 1.000000001*w[1] - ABS(orig)*1.1e-30;
+    if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+    else {
+      t = (orig*hpinv.x + toint.x);
+      xn = t - toint.x;
+      v.x = t;
+      y = (orig - xn*mp1.x) - xn*mp2.x;
+      n =v.i[LOW_HALF]&3;
+      da = xn*pp3.x;
+      t=y-da;
+      da = (y-t)-da;
+      y = xn*pp4.x;
+      a = t - y;
+      da = ((t-a)-y)+da;
+      if (n&2) {a=-a; da=-da;}
+      (a>0)? dubsin(a,da,w) : dubsin(-a,-da,w);
+      cor = (w[1]>0)? 1.000000001*w[1] + ABS(orig)*1.1e-40 : 1.000000001*w[1] - ABS(orig)*1.1e-40;
+      if (w[0] == w[0]+cor) return (a>0)?w[0]:-w[0];
+      else return mpsin1(orig);
+    }
+  }
+}
+/***************************************************************************/
+/*  Routine compute sin(x+dx)   (Double-Length number) where x in first or  */
+/*  third quarter of unit circle.Routine receive also (right argument) the  */
+/*  original   value of x for computing error of result.And if result not  */
+/* accurate enough routine calls  mpsin1   or dubsin                       */
+/***************************************************************************/
+
+static double sloww1(double x, double dx, double orig) {
+  mynumber u;
+  double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,c1,c2,xx,cor,res;
+  static const double t22 = 6291456.0;
+  int4 k;
+  y=ABS(x);
+  u.x=big.x+y;
+  y=y-(u.x-big.x);
+  dx=(x>0)?dx:-dx;
+  xx=y*y;
+  s = y*xx*(sn3 +xx*sn5);
+  c = xx*(cs2 +xx*(cs4 + xx*cs6));
+  k=u.i[LOW_HALF]<<2;
+  sn=sincos.x[k];
+  ssn=sincos.x[k+1];
+  cs=sincos.x[k+2];
+  ccs=sincos.x[k+3];
+  y1 = (y+t22)-t22;
+  y2 = (y - y1)+dx;
+  c1 = (cs+t22)-t22;
+  c2=(cs-c1)+ccs;
+  cor=(ssn+s*ccs+cs*s+c2*y+c1*y2-sn*y*dx)-sn*c;
+  y=sn+c1*y1;
+  cor = cor+((sn-y)+c1*y1);
+  res=y+cor;
+  cor=(y-res)+cor;
+  cor = (cor>0)? 1.0005*cor+3.1e-30*ABS(orig) : 1.0005*cor-3.1e-30*ABS(orig);
+  if (res == res + cor) return (x>0)?res:-res;
+  else {
+    dubsin(ABS(x),dx,w);
+    cor = (w[1]>0)? 1.000000005*w[1]+1.1e-30*ABS(orig) : 1.000000005*w[1]-1.1e-30*ABS(orig);
+    if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+  else  return mpsin1(orig);
+  }
+}
+/***************************************************************************/
+/*  Routine compute sin(x+dx)   (Double-Length number) where x in second or */
+/*  fourth quarter of unit circle.Routine receive also  the  original value */
+/* and quarter(n= 1or 3)of x for computing error of result.And if result not*/
+/* accurate enough routine calls  mpsin1   or dubsin                       */
+/***************************************************************************/
+
+static double sloww2(double x, double dx, double orig, int n) {
+  mynumber u;
+  double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,e1,e2,xx,cor,res;
+  static const double t22 = 6291456.0;
+  int4 k;
+  y=ABS(x);
+  u.x=big.x+y;
+  y=y-(u.x-big.x);
+  dx=(x>0)?dx:-dx;
+  xx=y*y;
+  s = y*xx*(sn3 +xx*sn5);
+  c = y*dx+xx*(cs2 +xx*(cs4 + xx*cs6));
+  k=u.i[LOW_HALF]<<2;
+  sn=sincos.x[k];
+  ssn=sincos.x[k+1];
+  cs=sincos.x[k+2];
+  ccs=sincos.x[k+3];
+
+  y1 = (y+t22)-t22;
+  y2 = (y - y1)+dx;
+  e1 = (sn+t22)-t22;
+  e2=(sn-e1)+ssn;
+  cor=(ccs-cs*c-e1*y2-e2*y)-sn*s;
+  y=cs-e1*y1;
+  cor = cor+((cs-y)-e1*y1);
+  res=y+cor;
+  cor=(y-res)+cor;
+  cor = (cor>0)? 1.0005*cor+3.1e-30*ABS(orig) : 1.0005*cor-3.1e-30*ABS(orig);
+  if (res == res + cor) return (n&2)?-res:res;
+  else {
+   docos(ABS(x),dx,w);
+   cor = (w[1]>0)? 1.000000005*w[1]+1.1e-30*ABS(orig) : 1.000000005*w[1]-1.1e-30*ABS(orig);
+   if (w[0] == w[0]+cor) return (n&2)?-w[0]:w[0];
+   else  return mpsin1(orig);
+  }
+}
+/***************************************************************************/
+/*  Routine compute sin(x+dx) or cos(x+dx) (Double-Length number) where x   */
+/* is small enough to use Taylor series around zero and   (x+dx)            */
+/* in first or third quarter of unit circle.Routine receive also            */
+/* (right argument) the  original   value of x for computing error of      */
+/* result.And if result not accurate enough routine calls other routines    */
+/***************************************************************************/
+
+static double bsloww(double x,double dx, double orig,int n) {
+  static const double th2_36 = 206158430208.0;   /*    1.5*2**37   */
+  double y,x1,x2,xx,r,t,res,cor,w[2],a,da,xn;
+  union {int4 i[2]; double x;} v;
+  x1=(x+th2_36)-th2_36;
+  y = aa.x*x1*x1*x1;
+  r=x+y;
+  x2=(x-x1)+dx;
+  xx=x*x;
+  t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + bb.x)*xx + 3.0*aa.x*x1*x2)*x +aa.x*x2*x2*x2+dx;
+  t=((x-r)+y)+t;
+  res=r+t;
+  cor = (r-res)+t;
+  cor = (cor>0)? 1.0005*cor+1.1e-24 : 1.0005*cor-1.1e-24;
+  if (res == res + cor) return res;
+  else {
+    (x>0)? dubsin(x,dx,w) : dubsin(-x,-dx,w);
+    cor = (w[1]>0)? 1.000000001*w[1] + 1.1e-24 : 1.000000001*w[1] - 1.1e-24;
+    if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+    else return (n&1)?mpcos1(orig):mpsin1(orig);
+  }
+}
+
+/***************************************************************************/
+/*  Routine compute sin(x+dx)  or cos(x+dx) (Double-Length number) where x  */
+/* in first or third quarter of unit circle.Routine receive also            */
+/* (right argument) the original  value of x for computing error of result.*/
+/* And if result not  accurate enough routine calls  other routines         */
+/***************************************************************************/
+
+static double bsloww1(double x, double dx, double orig,int n) {
+mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,c1,c2,xx,cor,res;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ u.x=big.x+y;
+ y=y-(u.x-big.x);
+ dx=(x>0)?dx:-dx;
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ y1 = (y+t22)-t22;
+ y2 = (y - y1)+dx;
+ c1 = (cs+t22)-t22;
+ c2=(cs-c1)+ccs;
+ cor=(ssn+s*ccs+cs*s+c2*y+c1*y2-sn*y*dx)-sn*c;
+ y=sn+c1*y1;
+ cor = cor+((sn-y)+c1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ cor = (cor>0)? 1.0005*cor+1.1e-24 : 1.0005*cor-1.1e-24;
+ if (res == res + cor) return (x>0)?res:-res;
+ else {
+   dubsin(ABS(x),dx,w);
+   cor = (w[1]>0)? 1.000000005*w[1]+1.1e-24: 1.000000005*w[1]-1.1e-24;
+   if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+   else  return (n&1)?mpcos1(orig):mpsin1(orig);
+ }
+}
+
+/***************************************************************************/
+/*  Routine compute sin(x+dx)  or cos(x+dx) (Double-Length number) where x  */
+/* in second or fourth quarter of unit circle.Routine receive also  the     */
+/* original value and quarter(n= 1or 3)of x for computing error of result.  */
+/* And if result not accurate enough routine calls  other routines          */
+/***************************************************************************/
+
+static double bsloww2(double x, double dx, double orig, int n) {
+mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,e1,e2,xx,cor,res;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ u.x=big.x+y;
+ y=y-(u.x-big.x);
+ dx=(x>0)?dx:-dx;
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = y*dx+xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+
+ y1 = (y+t22)-t22;
+ y2 = (y - y1)+dx;
+ e1 = (sn+t22)-t22;
+ e2=(sn-e1)+ssn;
+ cor=(ccs-cs*c-e1*y2-e2*y)-sn*s;
+ y=cs-e1*y1;
+ cor = cor+((cs-y)-e1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ cor = (cor>0)? 1.0005*cor+1.1e-24 : 1.0005*cor-1.1e-24;
+ if (res == res + cor) return (n&2)?-res:res;
+ else {
+   docos(ABS(x),dx,w);
+   cor = (w[1]>0)? 1.000000005*w[1]+1.1e-24 : 1.000000005*w[1]-1.1e-24;
+   if (w[0] == w[0]+cor) return (n&2)?-w[0]:w[0];
+   else  return (n&1)?mpsin1(orig):mpcos1(orig);
+ }
+}
+
+/************************************************************************/
+/*  Routine compute cos(x) for  2^-27 < |x|< 0.25 by  Taylor with more   */
+/* precision  and if still doesn't accurate enough by mpcos   or docos  */
+/************************************************************************/
+
+static double cslow2(double x) {
+  mynumber u;
+  double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,e1,e2,xx,cor,res;
+  static const double t22 = 6291456.0;
+  int4 k;
+  y=ABS(x);
+  u.x = big.x+y;
+  y = y-(u.x-big.x);
+  xx=y*y;
+  s = y*xx*(sn3 +xx*sn5);
+  c = xx*(cs2 +xx*(cs4 + xx*cs6));
+  k=u.i[LOW_HALF]<<2;
+  sn=sincos.x[k];
+  ssn=sincos.x[k+1];
+  cs=sincos.x[k+2];
+  ccs=sincos.x[k+3];
+  y1 = (y+t22)-t22;
+  y2 = y - y1;
+  e1 = (sn+t22)-t22;
+  e2=(sn-e1)+ssn;
+  cor=(ccs-cs*c-e1*y2-e2*y)-sn*s;
+  y=cs-e1*y1;
+  cor = cor+((cs-y)-e1*y1);
+  res=y+cor;
+  cor=(y-res)+cor;
+  if (res == res+1.0005*cor)
+    return res;
+  else {
+    y=ABS(x);
+    docos(y,0,w);
+    if (w[0] == w[0]+1.000000005*w[1]) return w[0];
+    else return mpcos(x,0);
+  }
+}
+
+/***************************************************************************/
+/*  Routine compute cos(x+dx) (Double-Length number) where x is small enough*/
+/* to use Taylor series around zero and   (x+dx) .Routine receive also      */
+/* (right argument) the  original   value of x for computing error of      */
+/* result.And if result not accurate enough routine calls other routines    */
+/***************************************************************************/
+
+
+static double csloww(double x,double dx, double orig) {
+  static const double th2_36 = 206158430208.0;   /*    1.5*2**37   */
+  double y,x1,x2,xx,r,t,res,cor,w[2],a,da,xn;
+  union {int4 i[2]; double x;} v;
+  int4 n;
+  x1=(x+th2_36)-th2_36;
+  y = aa.x*x1*x1*x1;
+  r=x+y;
+  x2=(x-x1)+dx;
+  xx=x*x;
+    /* Taylor series */
+  t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + bb.x)*xx + 3.0*aa.x*x1*x2)*x +aa.x*x2*x2*x2+dx;
+  t=((x-r)+y)+t;
+  res=r+t;
+  cor = (r-res)+t;
+  cor = (cor>0)? 1.0005*cor+ABS(orig)*3.1e-30 : 1.0005*cor-ABS(orig)*3.1e-30;
+  if (res == res + cor) return res;
+  else {
+    (x>0)? dubsin(x,dx,w) : dubsin(-x,-dx,w);
+    cor = (w[1]>0)? 1.000000001*w[1] + ABS(orig)*1.1e-30 : 1.000000001*w[1] - ABS(orig)*1.1e-30;
+    if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+    else {
+      t = (orig*hpinv.x + toint.x);
+      xn = t - toint.x;
+      v.x = t;
+      y = (orig - xn*mp1.x) - xn*mp2.x;
+      n =v.i[LOW_HALF]&3;
+      da = xn*pp3.x;
+      t=y-da;
+      da = (y-t)-da;
+      y = xn*pp4.x;
+      a = t - y;
+      da = ((t-a)-y)+da;
+      if (n==1) {a=-a; da=-da;}
+      (a>0)? dubsin(a,da,w) : dubsin(-a,-da,w);
+      cor = (w[1]>0)? 1.000000001*w[1] + ABS(orig)*1.1e-40 : 1.000000001*w[1] - ABS(orig)*1.1e-40;
+      if (w[0] == w[0]+cor) return (a>0)?w[0]:-w[0];
+      else return mpcos1(orig);
+    }
+  }
+}
+
+/***************************************************************************/
+/*  Routine compute sin(x+dx)   (Double-Length number) where x in first or  */
+/*  third quarter of unit circle.Routine receive also (right argument) the  */
+/*  original   value of x for computing error of result.And if result not  */
+/* accurate enough routine calls  other routines                            */
+/***************************************************************************/
+
+static double csloww1(double x, double dx, double orig) {
+  mynumber u;
+  double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,c1,c2,xx,cor,res;
+  static const double t22 = 6291456.0;
+  int4 k;
+  y=ABS(x);
+  u.x=big.x+y;
+  y=y-(u.x-big.x);
+  dx=(x>0)?dx:-dx;
+  xx=y*y;
+  s = y*xx*(sn3 +xx*sn5);
+  c = xx*(cs2 +xx*(cs4 + xx*cs6));
+  k=u.i[LOW_HALF]<<2;
+  sn=sincos.x[k];
+  ssn=sincos.x[k+1];
+  cs=sincos.x[k+2];
+  ccs=sincos.x[k+3];
+  y1 = (y+t22)-t22;
+  y2 = (y - y1)+dx;
+  c1 = (cs+t22)-t22;
+  c2=(cs-c1)+ccs;
+  cor=(ssn+s*ccs+cs*s+c2*y+c1*y2-sn*y*dx)-sn*c;
+  y=sn+c1*y1;
+  cor = cor+((sn-y)+c1*y1);
+  res=y+cor;
+  cor=(y-res)+cor;
+  cor = (cor>0)? 1.0005*cor+3.1e-30*ABS(orig) : 1.0005*cor-3.1e-30*ABS(orig);
+  if (res == res + cor) return (x>0)?res:-res;
+  else {
+    dubsin(ABS(x),dx,w);
+    cor = (w[1]>0)? 1.000000005*w[1]+1.1e-30*ABS(orig) : 1.000000005*w[1]-1.1e-30*ABS(orig);
+    if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+    else  return mpcos1(orig);
+  }
+}
+
+
+/***************************************************************************/
+/*  Routine compute sin(x+dx)   (Double-Length number) where x in second or */
+/*  fourth quarter of unit circle.Routine receive also  the  original value */
+/* and quarter(n= 1or 3)of x for computing error of result.And if result not*/
+/* accurate enough routine calls  other routines                            */
+/***************************************************************************/
+
+static double csloww2(double x, double dx, double orig, int n) {
+  mynumber u;
+  double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,e1,e2,xx,cor,res;
+  static const double t22 = 6291456.0;
+  int4 k;
+  y=ABS(x);
+  u.x=big.x+y;
+  y=y-(u.x-big.x);
+  dx=(x>0)?dx:-dx;
+  xx=y*y;
+  s = y*xx*(sn3 +xx*sn5);
+  c = y*dx+xx*(cs2 +xx*(cs4 + xx*cs6));
+  k=u.i[LOW_HALF]<<2;
+  sn=sincos.x[k];
+  ssn=sincos.x[k+1];
+  cs=sincos.x[k+2];
+  ccs=sincos.x[k+3];
+
+  y1 = (y+t22)-t22;
+  y2 = (y - y1)+dx;
+  e1 = (sn+t22)-t22;
+  e2=(sn-e1)+ssn;
+  cor=(ccs-cs*c-e1*y2-e2*y)-sn*s;
+  y=cs-e1*y1;
+  cor = cor+((cs-y)-e1*y1);
+  res=y+cor;
+  cor=(y-res)+cor;
+  cor = (cor>0)? 1.0005*cor+3.1e-30*ABS(orig) : 1.0005*cor-3.1e-30*ABS(orig);
+  if (res == res + cor) return (n)?-res:res;
+  else {
+    docos(ABS(x),dx,w);
+    cor = (w[1]>0)? 1.000000005*w[1]+1.1e-30*ABS(orig) : 1.000000005*w[1]-1.1e-30*ABS(orig);
+    if (w[0] == w[0]+cor) return (n)?-w[0]:w[0];
+    else  return mpcos1(orig);
+  }
+}
+
 #ifdef NO_LONG_DOUBLE
-strong_alias (__sin, __sinl)
-weak_alias (__sin, sinl)
+weak_alias (sin, sinl)
+weak_alias (cos, cosl)
 #endif