tan.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/tan.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 double
00015 tan(double x)
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         int negative = x < 0;
00023         int invert = 0;
00024         double  y;
00025         static double   p[] = {
00026                  1.0,
00027                 -0.13338350006421960681e+0,
00028                  0.34248878235890589960e-2,
00029                 -0.17861707342254426711e-4
00030         };
00031         static double   q[] = {
00032                  1.0,
00033                 -0.46671683339755294240e+0,
00034                  0.25663832289440112864e-1,
00035                 -0.31181531907010027307e-3,
00036                  0.49819433993786512270e-6
00037         };
00038 
00039         if (__IsNan(x)) {
00040                 errno = EDOM;
00041                 return x;
00042         }
00043         if (negative) x = -x;
00044  
00045         /* ??? avoid loss of significance, error if x is too large ??? */
00046 
00047         y = x * M_2_PI + 0.5;
00048 
00049         if (y >= DBL_MAX/M_PI_2) return 0.0;
00050 
00051         /*      Use extended precision to calculate reduced argument.
00052                 Here we used 12 bits of the mantissa for a1.
00053                 Also split x in integer part x1 and fraction part x2.
00054         */
00055     #define A1 1.57080078125
00056     #define A2 -4.454455103380768678308e-6
00057         {
00058                 double x1, x2;
00059 
00060                 modf(y, &y);
00061                 if (modf(0.5*y, &x1)) invert = 1;
00062                 x2 = modf(x, &x1);
00063                 x = x1 - y * A1;
00064                 x += x2;
00065                 x -= y * A2;
00066     #undef A1
00067     #undef A2
00068         }
00069 
00070         /* ??? avoid underflow ??? */
00071         y = x * x;
00072         x += x * y * POLYNOM2(y, p+1);
00073         y = POLYNOM4(y, q);
00074         if (negative) x = -x;
00075         return invert ? -y/x : x/y;
00076 }

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