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 2006 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #pragma weak __atanf = atanf 32 33 34 /* 35 * float atanf(float x); 36 * Table look-up algorithm 37 * By K.C. Ng, March 9, 1989 38 * 39 * Algorithm. 40 * 41 * The algorithm is based on atan(x)=atan(y)+atan((x-y)/(1+x*y)). 42 * We use poly1(x) to approximate atan(x) for x in [0,1/8] with 43 * error (relative) 44 * |(atan(x)-poly1(x))/x|<= 2^-115.94 long double 45 * |(atan(x)-poly1(x))/x|<= 2^-58.85 double 46 * |(atan(x)-poly1(x))/x|<= 2^-25.53 float 47 * and use poly2(x) to approximate atan(x) for x in [0,1/65] with 48 * error (absolute) 49 * |atan(x)-poly2(x)|<= 2^-122.15 long double 50 * |atan(x)-poly2(x)|<= 2^-64.79 double 51 * |atan(x)-poly2(x)|<= 2^-35.36 float 52 * and use poly3(x) to approximate atan(x) for x in [1/8,7/16] with 53 * error (relative, on for single precision) 54 * |(atan(x)-poly1(x))/x|<= 2^-25.53 float 55 * 56 * Here poly1-3 are odd polynomial with the following form: 57 * x + x^3*(a1+x^2*(a2+...)) 58 * 59 * (0). Purge off Inf and NaN and 0 60 * (1). Reduce x to positive by atan(x) = -atan(-x). 61 * (2). For x <= 1/8, use 62 * (2.1) if x < 2^(-prec/2-2), atan(x) = x with inexact 63 * (2.2) Otherwise 64 * atan(x) = poly1(x) 65 * (3). For x >= 8 then 66 * (3.1) if x >= 2^(prec+2), atan(x) = atan(inf) - pio2lo 67 * (3.2) if x >= 2^(prec/3+2), atan(x) = atan(inf) - 1/x 68 * (3.3) if x > 65, atan(x) = atan(inf) - poly2(1/x) 69 * (3.4) Otherwise, atan(x) = atan(inf) - poly1(1/x) 70 * 71 * (4). Now x is in (0.125, 8) 72 * Find y that match x to 4.5 bit after binary (easy). 73 * If iy is the high word of y, then 74 * single : j = (iy - 0x3e000000) >> 19 75 * (single is modified to (iy-0x3f000000)>>19) 76 * double : j = (iy - 0x3fc00000) >> 16 77 * quad : j = (iy - 0x3ffc0000) >> 12 78 * 79 * Let s = (x-y)/(1+x*y). Then 80 * atan(x) = atan(y) + poly1(s) 81 * = _TBL_r_atan_hi[j] + (_TBL_r_atan_lo[j] + poly2(s) ) 82 * 83 * Note. |s| <= 1.5384615385e-02 = 1/65. Maxium occurs at x = 1.03125 84 * 85 */ 86 87 #include "libm.h" 88 89 extern const float _TBL_r_atan_hi[], _TBL_r_atan_lo[]; 90 static const float big = 1.0e37F, 91 one = 1.0F, 92 p1 = -3.333185951111688247225368498733544672172e-0001F, 93 p2 = 1.969352894213455405211341983203180636021e-0001F, 94 q1 = -3.332921964095646819563419704110132937456e-0001F, 95 a1 = -3.333323465223893614063523351509338934592e-0001F, 96 a2 = 1.999425625935277805494082274808174062403e-0001F, 97 a3 = -1.417547090509737780085769846290301788559e-0001F, 98 a4 = 1.016250813871991983097273733227432685084e-0001F, 99 a5 = -5.137023693688358515753093811791755221805e-0002F, 100 pio2hi = 1.570796371e+0000F, 101 pio2lo = -4.371139000e-0008F; 102 103 104 float 105 atanf(float xx) 106 { 107 float x, y, z, r, p, s; 108 volatile double dummy __unused; 109 int ix, iy, sign, j; 110 111 x = xx; 112 ix = *(int *)&x; 113 sign = ix & 0x80000000; 114 ix ^= sign; 115 116 /* for |x| < 1/8 */ 117 if (ix < 0x3e000000) { 118 if (ix < 0x38800000) { /* if |x| < 2**(-prec/2-2) */ 119 dummy = big + x; /* get inexact flag if x != 0 */ 120 #ifdef lint 121 dummy = dummy; 122 #endif 123 return (x); 124 } 125 126 z = x * x; 127 128 if (ix < 0x3c000000) { /* if |x| < 2**(-prec/4-1) */ 129 x = x + (x * z) * p1; 130 return (x); 131 } else { 132 x = x + (x * z) * (p1 + z * p2); 133 return (x); 134 } 135 } 136 137 /* for |x| >= 8.0 */ 138 if (ix >= 0x41000000) { 139 *(int *)&x = ix; 140 141 if (ix < 0x42820000) { /* x < 65 */ 142 r = one / x; 143 z = r * r; 144 y = r * (one + z * (p1 + z * p2)); /* poly1 */ 145 y -= pio2lo; 146 } else if (ix < 0x44800000) { /* x < 2**(prec/3+2) */ 147 r = one / x; 148 z = r * r; 149 y = r * (one + z * q1); /* poly2 */ 150 y -= pio2lo; 151 } else if (ix < 0x4c800000) { /* x < 2**(prec+2) */ 152 y = one / x - pio2lo; 153 } else if (ix < 0x7f800000) { /* x < inf */ 154 y = -pio2lo; 155 } else { /* x is inf or NaN */ 156 if (ix > 0x7f800000) 157 return (x * x); /* - -> * for Cheetah */ 158 159 y = -pio2lo; 160 } 161 162 if (sign == 0) 163 x = pio2hi - y; 164 else 165 x = y - pio2hi; 166 167 return (x); 168 } 169 170 /* now x is between 1/8 and 8 */ 171 if (ix < 0x3f000000) { /* between 1/8 and 1/2 */ 172 z = x * x; 173 x = x + (x * z) * (a1 + z * (a2 + z * (a3 + z * (a4 + z * 174 a5)))); 175 return (x); 176 } 177 178 *(int *)&x = ix; 179 iy = (ix + 0x00040000) & 0x7ff80000; 180 *(int *)&y = iy; 181 j = (iy - 0x3f000000) >> 19; 182 183 if (ix == iy) { 184 p = x - y; /* p=0.0 */ 185 } else { 186 if (sign == 0) 187 s = (x - y) / (one + x * y); 188 else 189 s = (y - x) / (one + x * y); 190 191 z = s * s; 192 p = s * (one + z * q1); 193 } 194 195 if (sign == 0) { 196 r = p + _TBL_r_atan_lo[j]; 197 x = r + _TBL_r_atan_hi[j]; 198 } else { 199 r = p - _TBL_r_atan_lo[j]; 200 x = r - _TBL_r_atan_hi[j]; 201 } 202 203 return (x); 204 }