about summary refs log tree commit diff
path: root/sysdeps/libm-ieee754/k_cos.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-03-05 21:41:30 +0000
committerRoland McGrath <roland@gnu.org>1996-03-05 21:41:30 +0000
commitf7eac6eb504f4baf13dbb4d26717942df050ebe6 (patch)
tree95ff129c06c7f6f246a5e2bfa489ba6382659d19 /sysdeps/libm-ieee754/k_cos.c
parent1521668f2afae1dc2ef5d7ffaeb84353b36874dd (diff)
downloadglibc-f7eac6eb504f4baf13dbb4d26717942df050ebe6.tar.gz
glibc-f7eac6eb504f4baf13dbb4d26717942df050ebe6.tar.xz
glibc-f7eac6eb504f4baf13dbb4d26717942df050ebe6.zip
Mon Mar 4 20:54:40 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
	* Makeconfig ($(common-objpfx)config.make): Depend on config.h.in.


Mon Mar  4 17:35:09 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* hurd/catch-signal.c (hurd_safe_memmove): New function.
	(hurd_safe_copyin, hurd_safe_copyout): New functions.
	* hurd/hurd/sigpreempt.h: Declare them.

Sun Mar  3 08:43:44 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	Replace math code with fdlibm from Sun as modified for netbsd by
	JT Conklin and Ian Taylor, including x86 FPU support.
	* sysdeps/libm-ieee754, sysdeps/libm-i387: New directories.
	* math/math_private.h: New file.
	* sysdeps/i386/fpu/Implies: New file.
	* sysdeps/ieee754/Implies: New file.
	* math/machine/asm.h, math/machine/endian.h: New files.
	* math/Makefile, math/math.h: Rewritten.
	* mathcalls.h, math/mathcalls.h: New file, broken out of math.h.
	* math/finite.c: File removed.
	* sysdeps/generic/Makefile [$(subdir)=math]: Frobnication removed.

	* math/test-math.c: Include errno.h and string.h.

	* sysdeps/unix/bsd/dirstream.h: File removed.
	* sysdeps/unix/bsd/readdir.c: File removed.
Diffstat (limited to 'sysdeps/libm-ieee754/k_cos.c')
-rw-r--r--sysdeps/libm-ieee754/k_cos.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/sysdeps/libm-ieee754/k_cos.c b/sysdeps/libm-ieee754/k_cos.c
new file mode 100644
index 0000000000..d8740b3508
--- /dev/null
+++ b/sysdeps/libm-ieee754/k_cos.c
@@ -0,0 +1,96 @@
+/* @(#)k_cos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * 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: k_cos.c,v 1.8 1995/05/10 20:46:22 jtc Exp $";
+#endif
+
+/*
+ * __kernel_cos( x,  y )
+ * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x. 
+ *
+ * Algorithm
+ *	1. Since cos(-x) = cos(x), we need only to consider positive x.
+ *	2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
+ *	3. cos(x) is approximated by a polynomial of degree 14 on
+ *	   [0,pi/4]
+ *		  	                 4            14
+ *	   	cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
+ *	   where the remez error is
+ *	
+ * 	|              2     4     6     8     10    12     14 |     -58
+ * 	|cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  )| <= 2
+ * 	|    					               | 
+ * 
+ * 	               4     6     8     10    12     14 
+ *	4. let r = C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  , then
+ *	       cos(x) = 1 - x*x/2 + r
+ *	   since cos(x+y) ~ cos(x) - sin(x)*y 
+ *			  ~ cos(x) - x*y,
+ *	   a correction term is necessary in cos(x) and hence
+ *		cos(x+y) = 1 - (x*x/2 - (r - x*y))
+ *	   For better accuracy when x > 0.3, let qx = |x|/4 with
+ *	   the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
+ *	   Then
+ *		cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
+ *	   Note that 1-qx and (x*x/2-qx) is EXACT here, and the
+ *	   magnitude of the latter is at least a quarter of x*x/2,
+ *	   thus, reducing the rounding error in the subtraction.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+C1  =  4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
+C2  = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
+C3  =  2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
+C4  = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
+C5  =  2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
+C6  = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
+
+#ifdef __STDC__
+	double __kernel_cos(double x, double y)
+#else
+	double __kernel_cos(x, y)
+	double x,y;
+#endif
+{
+	double a,hz,z,r,qx;
+	int32_t ix;
+	GET_HIGH_WORD(ix,x);
+	ix &= 0x7fffffff;			/* ix = |x|'s high word*/
+	if(ix<0x3e400000) {			/* if x < 2**27 */
+	    if(((int)x)==0) return one;		/* generate inexact */
+	}
+	z  = x*x;
+	r  = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
+	if(ix < 0x3FD33333) 			/* if |x| < 0.3 */ 
+	    return one - (0.5*z - (z*r - x*y));
+	else {
+	    if(ix > 0x3fe90000) {		/* x > 0.78125 */
+		qx = 0.28125;
+	    } else {
+	        INSERT_WORDS(qx,ix-0x00200000,0);	/* x/4 */
+	    }
+	    hz = 0.5*z-qx;
+	    a  = one-qx;
+	    return a - (hz - (z*r-x*y));
+	}
+}