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 __asinl = asinl 32 33 /* 34 * asinl(x) = atan2l(x,sqrt(1-x*x)); 35 * 36 * For better accuracy, 1-x*x is computed as follows 37 * 1-x*x if x < 0.5, 38 * 2*(1-|x|)-(1-|x|)*(1-|x|) if x >= 0.5. 39 * 40 * Special cases: 41 * if x is NaN, return x itself; 42 * if |x|>1, return NaN with invalid signal. 43 */ 44 45 #include "libm.h" 46 47 static const long double zero = 0.0L, small = 1.0e-20L, half = 0.5L, one = 1.0L; 48 49 #ifndef lint 50 static const long double big = 1.0e+20L; 51 #endif 52 53 long double 54 asinl(long double x) 55 { 56 long double t, w; 57 58 #ifndef lint 59 volatile long double dummy; 60 #endif 61 62 w = fabsl(x); 63 64 if (isnanl(x)) { 65 return (x + x); 66 } else if (w <= half) { 67 if (w < small) { 68 #ifndef lint 69 dummy = w + big; 70 /* inexact if w != 0 */ 71 #endif 72 return (x); 73 } else { 74 return (atanl(x / sqrtl(one - x * x))); 75 } 76 } else if (w < one) { 77 t = one - w; 78 w = t + t; 79 return (atanl(x / sqrtl(w - t * t))); 80 } else if (w == one) { 81 return (atan2l(x, zero)); /* asin(+-1) = +- PI/2 */ 82 } else { 83 return (zero / zero); /* |x| > 1: invalid */ 84 } 85 }