OLD | NEW |
1 /* origin: FreeBSD /usr/src/lib/msun/src/s_atanf.c */ | 1 /* origin: FreeBSD /usr/src/lib/msun/src/s_atanf.c */ |
2 /* | 2 /* |
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. | 3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. |
4 */ | 4 */ |
5 /* | 5 /* |
6 * ==================================================== | 6 * ==================================================== |
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | 7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
8 * | 8 * |
9 * Developed at SunPro, a Sun Microsystems, Inc. business. | 9 * Developed at SunPro, a Sun Microsystems, Inc. business. |
10 * Permission to use, copy, modify, and distribute this | 10 * Permission to use, copy, modify, and distribute this |
11 * software is freely granted, provided that this notice | 11 * software is freely granted, provided that this notice |
12 * is preserved. | 12 * is preserved. |
13 * ==================================================== | 13 * ==================================================== |
14 */ | 14 */ |
15 | 15 |
16 | |
17 #include "libm.h" | 16 #include "libm.h" |
18 | 17 |
19 static const float atanhi[] = { | 18 static const float atanhi[] = { |
20 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ | 19 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ |
21 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */ | 20 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */ |
22 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */ | 21 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */ |
23 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */ | 22 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */ |
24 }; | 23 }; |
25 | 24 |
26 static const float atanlo[] = { | 25 static const float atanlo[] = { |
27 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */ | 26 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */ |
28 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */ | 27 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */ |
29 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */ | 28 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */ |
30 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ | 29 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ |
31 }; | 30 }; |
32 | 31 |
33 static const float aT[] = { | 32 static const float aT[] = { |
34 3.3333328366e-01, | 33 3.3333328366e-01, -1.9999158382e-01, 1.4253635705e-01, |
35 -1.9999158382e-01, | 34 -1.0648017377e-01, 6.1687607318e-02, |
36 1.4253635705e-01, | |
37 -1.0648017377e-01, | |
38 6.1687607318e-02, | |
39 }; | 35 }; |
40 | 36 |
41 float atanf(float x) | 37 float atanf(float x) { |
42 { | 38 float_t w, s1, s2, z; |
43 » float_t w,s1,s2,z; | 39 uint32_t ix, sign; |
44 » uint32_t ix,sign; | 40 int id; |
45 » int id; | |
46 | 41 |
47 » GET_FLOAT_WORD(ix, x); | 42 GET_FLOAT_WORD(ix, x); |
48 » sign = ix>>31; | 43 sign = ix >> 31; |
49 » ix &= 0x7fffffff; | 44 ix &= 0x7fffffff; |
50 » if (ix >= 0x4c800000) { /* if |x| >= 2**26 */ | 45 if (ix >= 0x4c800000) { /* if |x| >= 2**26 */ |
51 » » if (isnan(x)) | 46 if (isnan(x)) |
52 » » » return x; | 47 return x; |
53 » » z = atanhi[3] + 0x1p-120f; | 48 z = atanhi[3] + 0x1p-120f; |
54 » » return sign ? -z : z; | 49 return sign ? -z : z; |
55 » } | 50 } |
56 » if (ix < 0x3ee00000) { /* |x| < 0.4375 */ | 51 if (ix < 0x3ee00000) { /* |x| < 0.4375 */ |
57 » » if (ix < 0x39800000) { /* |x| < 2**-12 */ | 52 if (ix < 0x39800000) { /* |x| < 2**-12 */ |
58 » » » if (ix < 0x00800000) | 53 if (ix < 0x00800000) |
59 » » » » /* raise underflow for subnormal x */ | 54 /* raise underflow for subnormal x */ |
60 » » » » FORCE_EVAL(x*x); | 55 FORCE_EVAL(x * x); |
61 » » » return x; | 56 return x; |
62 » » } | 57 } |
63 » » id = -1; | 58 id = -1; |
64 » } else { | 59 } else { |
65 » » x = fabsf(x); | 60 x = fabsf(x); |
66 » » if (ix < 0x3f980000) { /* |x| < 1.1875 */ | 61 if (ix < 0x3f980000) { /* |x| < 1.1875 */ |
67 » » » if (ix < 0x3f300000) { /* 7/16 <= |x| < 11/16 */ | 62 if (ix < 0x3f300000) { /* 7/16 <= |x| < 11/16 */ |
68 » » » » id = 0; | 63 id = 0; |
69 » » » » x = (2.0f*x - 1.0f)/(2.0f + x); | 64 x = (2.0f * x - 1.0f) / (2.0f + x); |
70 » » » } else { /* 11/16 <= |x| < 19/16 */ | 65 } else { /* 11/16 <= |x| < 19/16 */ |
71 » » » » id = 1; | 66 id = 1; |
72 » » » » x = (x - 1.0f)/(x + 1.0f); | 67 x = (x - 1.0f) / (x + 1.0f); |
73 » » » } | 68 } |
74 » » } else { | 69 } else { |
75 » » » if (ix < 0x401c0000) { /* |x| < 2.4375 */ | 70 if (ix < 0x401c0000) { /* |x| < 2.4375 */ |
76 » » » » id = 2; | 71 id = 2; |
77 » » » » x = (x - 1.5f)/(1.0f + 1.5f*x); | 72 x = (x - 1.5f) / (1.0f + 1.5f * x); |
78 » » » } else { /* 2.4375 <= |x| < 2**26 */ | 73 } else { /* 2.4375 <= |x| < 2**26 */ |
79 » » » » id = 3; | 74 id = 3; |
80 » » » » x = -1.0f/x; | 75 x = -1.0f / x; |
81 » » » } | 76 } |
82 » » } | 77 } |
83 » } | 78 } |
84 » /* end of argument reduction */ | 79 /* end of argument reduction */ |
85 » z = x*x; | 80 z = x * x; |
86 » w = z*z; | 81 w = z * z; |
87 » /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ | 82 /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ |
88 » s1 = z*(aT[0]+w*(aT[2]+w*aT[4])); | 83 s1 = z * (aT[0] + w * (aT[2] + w * aT[4])); |
89 » s2 = w*(aT[1]+w*aT[3]); | 84 s2 = w * (aT[1] + w * aT[3]); |
90 » if (id < 0) | 85 if (id < 0) |
91 » » return x - x*(s1+s2); | 86 return x - x * (s1 + s2); |
92 » z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); | 87 z = atanhi[id] - ((x * (s1 + s2) - atanlo[id]) - x); |
93 » return sign ? -z : z; | 88 return sign ? -z : z; |
94 } | 89 } |
OLD | NEW |