OLD | NEW |
1 /* origin: FreeBSD /usr/src/lib/msun/src/s_ctanhf.c */ | 1 /* origin: FreeBSD /usr/src/lib/msun/src/s_ctanhf.c */ |
2 /*- | 2 /*- |
3 * Copyright (c) 2011 David Schultz | 3 * Copyright (c) 2011 David Schultz |
4 * All rights reserved. | 4 * All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice unmodified, this list of conditions, and the following | 10 * notice unmodified, this list of conditions, and the following |
(...skipping 12 matching lines...) Expand all Loading... |
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 /* | 27 /* |
28 * Hyperbolic tangent of a complex argument z. See s_ctanh.c for details. | 28 * Hyperbolic tangent of a complex argument z. See s_ctanh.c for details. |
29 */ | 29 */ |
30 | 30 |
31 #include "libm.h" | 31 #include "libm.h" |
32 | 32 |
33 float complex ctanhf(float complex z) | 33 float complex ctanhf(float complex z) { |
34 { | 34 float x, y; |
35 » float x, y; | 35 float t, beta, s, rho, denom; |
36 » float t, beta, s, rho, denom; | 36 uint32_t hx, ix; |
37 » uint32_t hx, ix; | |
38 | 37 |
39 » x = crealf(z); | 38 x = crealf(z); |
40 » y = cimagf(z); | 39 y = cimagf(z); |
41 | 40 |
42 » GET_FLOAT_WORD(hx, x); | 41 GET_FLOAT_WORD(hx, x); |
43 » ix = hx & 0x7fffffff; | 42 ix = hx & 0x7fffffff; |
44 | 43 |
45 » if (ix >= 0x7f800000) { | 44 if (ix >= 0x7f800000) { |
46 » » if (ix & 0x7fffff) | 45 if (ix & 0x7fffff) |
47 » » » return CMPLXF(x, (y == 0 ? y : x * y)); | 46 return CMPLXF(x, (y == 0 ? y : x * y)); |
48 » » SET_FLOAT_WORD(x, hx - 0x40000000); | 47 SET_FLOAT_WORD(x, hx - 0x40000000); |
49 » » return CMPLXF(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)))
; | 48 return CMPLXF(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y))); |
50 » } | 49 } |
51 | 50 |
52 » if (!isfinite(y)) | 51 if (!isfinite(y)) |
53 » » return CMPLXF(ix ? y - y : x, y - y); | 52 return CMPLXF(ix ? y - y : x, y - y); |
54 | 53 |
55 » if (ix >= 0x41300000) { /* x >= 11 */ | 54 if (ix >= 0x41300000) { /* x >= 11 */ |
56 » » float exp_mx = expf(-fabsf(x)); | 55 float exp_mx = expf(-fabsf(x)); |
57 » » return CMPLXF(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx *
exp_mx); | 56 return CMPLXF(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx * exp_mx); |
58 » } | 57 } |
59 | 58 |
60 » t = tanf(y); | 59 t = tanf(y); |
61 » beta = 1.0 + t * t; | 60 beta = 1.0 + t * t; |
62 » s = sinhf(x); | 61 s = sinhf(x); |
63 » rho = sqrtf(1 + s * s); | 62 rho = sqrtf(1 + s * s); |
64 » denom = 1 + beta * s * s; | 63 denom = 1 + beta * s * s; |
65 » return CMPLXF((beta * rho * s) / denom, t / denom); | 64 return CMPLXF((beta * rho * s) / denom, t / denom); |
66 } | 65 } |
OLD | NEW |