sin.c

Go to the documentation of this file.
00001 /*
00002  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
00003  * See the copyright notice in the ACK home directory, in the file "Copyright".
00004  *
00005  * Author: Ceriel J.H. Jacobs
00006  */
00007 /* $Header: /opt/proj/minix/cvsroot/src/lib/math/sin.c,v 1.1.1.1 2005/04/21 14:56:26 beng Exp $ */
00008 
00009 #include        <math.h>
00010 #include        <float.h>
00011 #include        <errno.h>
00012 #include        "localmath.h"
00013 
00014 static double
00015 sinus(double x, int cos_flag)
00016 {
00017         /*      Algorithm and coefficients from:
00018                         "Software manual for the elementary functions"
00019                         by W.J. Cody and W. Waite, Prentice-Hall, 1980
00020         */
00021 
00022         static double r[] = {
00023                 -0.16666666666666665052e+0,
00024                  0.83333333333331650314e-2,
00025                 -0.19841269841201840457e-3,
00026                  0.27557319210152756119e-5,
00027                 -0.25052106798274584544e-7,
00028                  0.16058936490371589114e-9,
00029                 -0.76429178068910467734e-12,
00030                  0.27204790957888846175e-14
00031         };
00032 
00033         double  y;
00034         int     neg = 1;
00035 
00036         if (__IsNan(x)) {
00037                 errno = EDOM;
00038                 return x;
00039         }
00040         if (x < 0) {
00041                 x = -x;
00042                 neg = -1;
00043         }
00044         if (cos_flag) {
00045                 neg = 1;
00046                 y = M_PI_2 + x;
00047         }
00048         else    y = x;
00049 
00050         /* ??? avoid loss of significance, if y is too large, error ??? */
00051 
00052         y = y * M_1_PI + 0.5;
00053 
00054         if (y >= DBL_MAX/M_PI) return 0.0;
00055 
00056         /*      Use extended precision to calculate reduced argument.
00057                 Here we used 12 bits of the mantissa for a1.
00058                 Also split x in integer part x1 and fraction part x2.
00059         */
00060 #define A1 3.1416015625
00061 #define A2 -8.908910206761537356617e-6
00062         {
00063                 double x1, x2;
00064 
00065                 modf(y, &y);
00066                 if (modf(0.5*y, &x1)) neg = -neg;
00067                 if (cos_flag) y -= 0.5;
00068                 x2 = modf(x, &x1);
00069                 x = x1 - y * A1;
00070                 x += x2;
00071                 x -= y * A2;
00072 #undef A1
00073 #undef A2
00074         }
00075  
00076         if (x < 0) {
00077                 neg = -neg;
00078                 x = -x;
00079         }
00080 
00081         /* ??? avoid underflow ??? */
00082 
00083         y = x * x;
00084         x += x * y * POLYNOM7(y, r);
00085         return neg==-1 ? -x : x;
00086 }
00087 
00088 double
00089 sin(double x)
00090 {
00091         return sinus(x, 0);
00092 }
00093 
00094 double
00095 cos(double x)
00096 {
00097         if (x < 0) x = -x;
00098         return sinus(x, 1);
00099 }

Generated on Fri Apr 14 22:57:25 2006 for minix by  doxygen 1.4.6