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 __catanf = catanf 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 pi_2 = 1.570796326794896558e+00F, 41 zero = 0.0F, 42 half = 0.5F, 43 two = 2.0F, 44 one = 1.0F; 45 46 fcomplex 47 catanf(fcomplex z) 48 { 49 fcomplex ans; 50 float x, y, ax, ay, t; 51 double dx, dy, dt; 52 int hx, hy, ix, iy; 53 54 x = F_RE(z); 55 y = F_IM(z); 56 ax = fabsf(x); 57 ay = fabsf(y); 58 hx = THE_WORD(x); 59 hy = THE_WORD(y); 60 ix = hx & 0x7fffffff; 61 iy = hy & 0x7fffffff; 62 63 if (ix >= 0x7f800000) { /* x is inf or NaN */ 64 if (ix == 0x7f800000) { 65 F_RE(ans) = pi_2; 66 F_IM(ans) = zero; 67 } else { 68 F_RE(ans) = x * x; 69 70 if (iy == 0 || iy == 0x7f800000) 71 F_IM(ans) = zero; 72 else 73 F_IM(ans) = (fabsf(y) - ay) / (fabsf(y) - ay); 74 } 75 } else if (iy >= 0x7f800000) { /* y is inf or NaN */ 76 if (iy == 0x7f800000) { 77 F_RE(ans) = pi_2; 78 F_IM(ans) = zero; 79 } else { 80 F_RE(ans) = (fabsf(x) - ax) / (fabsf(x) - ax); 81 F_IM(ans) = y * y; 82 } 83 } else if (ix == 0) { 84 /* BEGIN CSTYLED */ 85 /* 86 * x = 0 87 * 1 1 88 * A = --- * atan2(2x, 1-x*x-y*y) = --- atan2(0,1-|y|) 89 * 2 2 90 * 91 * 1 [ (y+1)*(y+1) ] 1 2 1 2y 92 * B = - log [ ----------- ] = - log (1+ ---) or - log(1+ ----) 93 * 4 [ (y-1)*(y-1) ] 2 y-1 2 1-y 94 */ 95 /* END CSTYLED */ 96 t = one - ay; 97 98 if (iy == 0x3f800000) { 99 /* y=1: catan(0,1)=(0,+inf) with 1/0 signal */ 100 F_IM(ans) = ay / ax; 101 F_RE(ans) = zero; 102 } else if (iy > 0x3f800000) { /* y>1 */ 103 F_IM(ans) = half * log1pf(two / (-t)); 104 F_RE(ans) = pi_2; 105 } else { /* y<1 */ 106 F_IM(ans) = half * log1pf((ay + ay) / t); 107 F_RE(ans) = zero; 108 } 109 } else { 110 /* BEGIN CSTYLED */ 111 /* 112 * use double precision x,y 113 * 1 114 * A = --- * atan2(2x, 1-x*x-y*y) 115 * 2 116 * 117 * 1 [ x*x+(y+1)*(y+1) ] 1 4y 118 * B = - log [ --------------- ] = - log (1+ -----------------) 119 * 4 [ x*x+(y-1)*(y-1) ] 4 x*x + (y-1)*(y-1) 120 */ 121 /* END CSTYLED */ 122 123 #if defined(__i386) && !defined(__amd64) 124 int rp = __swapRP(fp_extended); 125 #endif 126 dx = (double)ax; 127 dy = (double)ay; 128 F_RE(ans) = (float)(0.5 * atan2(dx + dx, 1.0 - dx * dx - dy * 129 dy)); 130 dt = dy - 1.0; 131 F_IM(ans) = (float)(0.25 * log1p(4.0 * dy / (dx * dx + dt * 132 dt))); 133 134 #if defined(__i386) && !defined(__amd64) 135 if (rp != fp_extended) 136 (void) __swapRP(rp); 137 #endif 138 } 139 140 if (hx < 0) 141 F_RE(ans) = -F_RE(ans); 142 143 if (hy < 0) 144 F_IM(ans) = -F_IM(ans); 145 146 return (ans); 147 }