1 |
|
|
/* k_tanf.c -- float version of k_tan.c |
2 |
|
|
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. |
3 |
|
|
*/ |
4 |
|
|
|
5 |
|
|
/* |
6 |
|
|
* ==================================================== |
7 |
|
|
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
8 |
|
|
* |
9 |
|
|
* Developed at SunPro, a Sun Microsystems, Inc. business. |
10 |
|
|
* Permission to use, copy, modify, and distribute this |
11 |
|
|
* software is freely granted, provided that this notice |
12 |
|
|
* is preserved. |
13 |
|
|
* ==================================================== |
14 |
|
|
*/ |
15 |
|
|
|
16 |
|
|
#include "math.h" |
17 |
|
|
#include "math_private.h" |
18 |
|
|
|
19 |
|
|
static const float |
20 |
|
|
one = 1.0000000000e+00, /* 0x3f800000 */ |
21 |
|
|
pio4 = 7.8539812565e-01, /* 0x3f490fda */ |
22 |
|
|
pio4lo= 3.7748947079e-08, /* 0x33222168 */ |
23 |
|
|
T[] = { |
24 |
|
|
3.3333334327e-01, /* 0x3eaaaaab */ |
25 |
|
|
1.3333334029e-01, /* 0x3e088889 */ |
26 |
|
|
5.3968254477e-02, /* 0x3d5d0dd1 */ |
27 |
|
|
2.1869488060e-02, /* 0x3cb327a4 */ |
28 |
|
|
8.8632395491e-03, /* 0x3c11371f */ |
29 |
|
|
3.5920790397e-03, /* 0x3b6b6916 */ |
30 |
|
|
1.4562094584e-03, /* 0x3abede48 */ |
31 |
|
|
5.8804126456e-04, /* 0x3a1a26c8 */ |
32 |
|
|
2.4646313977e-04, /* 0x398137b9 */ |
33 |
|
|
7.8179444245e-05, /* 0x38a3f445 */ |
34 |
|
|
7.1407252108e-05, /* 0x3895c07a */ |
35 |
|
|
-1.8558637748e-05, /* 0xb79bae5f */ |
36 |
|
|
2.5907305826e-05, /* 0x37d95384 */ |
37 |
|
|
}; |
38 |
|
|
|
39 |
|
|
float |
40 |
|
|
__kernel_tanf(float x, float y, int iy) |
41 |
|
|
{ |
42 |
|
|
float z,r,v,w,s; |
43 |
|
|
int32_t ix,hx; |
44 |
|
|
GET_FLOAT_WORD(hx,x); |
45 |
|
|
ix = hx&0x7fffffff; /* high word of |x| */ |
46 |
|
|
if(ix<0x31800000) /* x < 2**-28 */ |
47 |
|
|
{if((int)x==0) { /* generate inexact */ |
48 |
|
|
if((ix|(iy+1))==0) return one/fabsf(x); |
49 |
|
|
else return (iy==1)? x: -one/x; |
50 |
|
|
} |
51 |
|
|
} |
52 |
|
|
if(ix>=0x3f2ca140) { /* |x|>=0.6744 */ |
53 |
|
|
if(hx<0) {x = -x; y = -y;} |
54 |
|
|
z = pio4-x; |
55 |
|
|
w = pio4lo-y; |
56 |
|
|
x = z+w; y = 0.0; |
57 |
|
|
} |
58 |
|
|
z = x*x; |
59 |
|
|
w = z*z; |
60 |
|
|
/* Break x^5*(T[1]+x^2*T[2]+...) into |
61 |
|
|
* x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + |
62 |
|
|
* x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) |
63 |
|
|
*/ |
64 |
|
|
r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11])))); |
65 |
|
|
v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12]))))); |
66 |
|
|
s = z*x; |
67 |
|
|
r = y + z*(s*(r+v)+y); |
68 |
|
|
r += T[0]*s; |
69 |
|
|
w = x+r; |
70 |
|
|
if(ix>=0x3f2ca140) { |
71 |
|
|
v = (float)iy; |
72 |
|
|
return (float)(1-((hx>>30)&2))*(v-(float)2.0*(x-(w*w/(w+v)-r))); |
73 |
|
|
} |
74 |
|
|
if(iy==1) return w; |
75 |
|
|
else { /* if allow error up to 2 ulp, |
76 |
|
|
simply return -1.0/(x+r) here */ |
77 |
|
|
/* compute -1.0/(x+r) accurately */ |
78 |
|
|
float a,t; |
79 |
|
|
int32_t i; |
80 |
|
|
z = w; |
81 |
|
|
GET_FLOAT_WORD(i,z); |
82 |
|
|
SET_FLOAT_WORD(z,i&0xfffff000); |
83 |
|
|
v = r-(z - x); /* z+v = r+x */ |
84 |
|
|
t = a = -(float)1.0/w; /* a = -1.0/w */ |
85 |
|
|
GET_FLOAT_WORD(i,t); |
86 |
|
|
SET_FLOAT_WORD(t,i&0xfffff000); |
87 |
|
|
s = (float)1.0+t*z; |
88 |
|
|
return t+a*(s+t*v); |
89 |
|
|
} |
90 |
|
|
} |