3 * Relative error approximations for function arguments near
7 * expm1(x) = exp(x) - 1
8 * cosm1(x) = cos(x) - 1
15 extern int isnan (double);
16 extern int isfinite (double);
17 extern double log ( double );
18 extern double polevl ( double, void *, int );
19 extern double p1evl ( double, void *, int );
20 extern double exp ( double );
21 extern double cos ( double );
23 double log(), polevl(), p1evl(), exp(), cos();
24 int isnan(), isfinite();
26 extern double INFINITY;
28 /* log1p(x) = log(1 + x) */
30 /* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
31 * 1/sqrt(2) <= x < sqrt(2)
32 * Theoretical peak relative error = 2.32e-20
34 static double LP[] = {
35 4.5270000862445199635215E-5,
36 4.9854102823193375972212E-1,
37 6.5787325942061044846969E0,
38 2.9911919328553073277375E1,
39 6.0949667980987787057556E1,
40 5.7112963590585538103336E1,
41 2.0039553499201281259648E1,
43 static double LQ[] = {
44 /* 1.0000000000000000000000E0,*/
45 1.5062909083469192043167E1,
46 8.3047565967967209469434E1,
47 2.2176239823732856465394E2,
48 3.0909872225312059774938E2,
49 2.1642788614495947685003E2,
50 6.0118660497603843919306E1,
53 #define SQRTH 0.70710678118654752440
54 #define SQRT2 1.41421356237309504880
62 if( (z < SQRTH) || (z > SQRT2) )
65 z = -0.5 * z + x * ( z * polevl( x, LP, 6 ) / p1evl( x, LQ, 6 ) );
71 /* expm1(x) = exp(x) - 1 */
73 /* e^x = 1 + 2x P(x^2)/( Q(x^2) - P(x^2) )
77 static double EP[3] = {
78 1.2617719307481059087798E-4,
79 3.0299440770744196129956E-2,
80 9.9999999999999999991025E-1,
82 static double EQ[4] = {
83 3.0019850513866445504159E-6,
84 2.5244834034968410419224E-3,
85 2.2726554820815502876593E-1,
86 2.0000000000000000000897E0,
104 if( (x < -0.5) || (x > 0.5) )
105 return( exp(x) - 1.0 );
107 r = x * polevl( xx, EP, 2 );
108 r = r/( polevl( xx, EQ, 3 ) - r );
114 /* cosm1(x) = cos(x) - 1 */
116 static double coscof[7] = {
117 4.7377507964246204691685E-14,
118 -1.1470284843425359765671E-11,
119 2.0876754287081521758361E-9,
120 -2.7557319214999787979814E-7,
121 2.4801587301570552304991E-5,
122 -1.3888888888888872993737E-3,
123 4.1666666666666666609054E-2,
133 if( (x < -PIO4) || (x > PIO4) )
134 return( cos(x) - 1.0 );
136 xx = -0.5*xx + xx * xx * polevl( xx, coscof, 6 );