1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #pragma weak __ccoshf = ccoshf 32 33 #include "libm.h" 34 #include "complex_wrapper.h" 35 36 #if defined(__i386) && !defined(__amd64) 37 extern int __swapRP(int); 38 #endif 39 40 static const float zero = 0.0F, half = 0.5F; 41 42 fcomplex 43 ccoshf(fcomplex z) 44 { 45 float t, x, y, S, C; 46 double w; 47 int hx, ix, hy, iy, n; 48 fcomplex ans; 49 50 x = F_RE(z); 51 y = F_IM(z); 52 hx = THE_WORD(x); 53 ix = hx & 0x7fffffff; 54 hy = THE_WORD(y); 55 iy = hy & 0x7fffffff; 56 x = fabsf(x); 57 y = fabsf(y); 58 59 sincosf(y, &S, &C); 60 61 if (ix >= 0x41600000) { /* |x| > 14 = prec/2 (14,28,34,60) */ 62 if (ix >= 0x42B171AA) { /* |x| > 88.722... ~ log(2**128) */ 63 if (ix >= 0x7f800000) { /* |x| is inf or NaN */ 64 if (iy == 0) { 65 F_RE(ans) = x; 66 F_IM(ans) = y; 67 } else if (iy >= 0x7f800000) { 68 F_RE(ans) = x; 69 F_IM(ans) = x - y; 70 } else { 71 F_RE(ans) = C * x; 72 F_IM(ans) = S * x; 73 } 74 } else { 75 #if defined(__i386) && !defined(__amd64) 76 int rp = __swapRP(fp_extended); 77 #endif 78 /* return (C, S) * exp(x) / 2 */ 79 w = __k_cexp((double)x, &n); 80 F_RE(ans) = (float)scalbn(C * w, n - 1); 81 F_IM(ans) = (float)scalbn(S * w, n - 1); 82 #if defined(__i386) && !defined(__amd64) 83 if (rp != fp_extended) 84 (void) __swapRP(rp); 85 #endif 86 } 87 } else { 88 t = expf(x) * half; 89 F_RE(ans) = C * t; 90 F_IM(ans) = S * t; 91 } 92 } else { 93 if (ix == 0) { /* x = 0, return (C,0) */ 94 F_RE(ans) = C; 95 F_IM(ans) = zero; 96 } else { 97 F_RE(ans) = C * coshf(x); 98 F_IM(ans) = S * sinhf(x); 99 } 100 } 101 102 if ((hx ^ hy) < 0) 103 F_IM(ans) = -F_IM(ans); 104 105 return (ans); 106 }