xref: /netbsd-src/external/gpl3/gcc.old/dist/libquadmath/math/acoshq.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1*627f7eb2Smrg /* e_acoshl.c -- long double version of e_acosh.c.
2*627f7eb2Smrg  * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
3*627f7eb2Smrg  */
4*627f7eb2Smrg 
5*627f7eb2Smrg /*
6*627f7eb2Smrg  * ====================================================
7*627f7eb2Smrg  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8*627f7eb2Smrg  *
9*627f7eb2Smrg  * Developed at SunPro, a Sun Microsystems, Inc. business.
10*627f7eb2Smrg  * Permission to use, copy, modify, and distribute this
11*627f7eb2Smrg  * software is freely granted, provided that this notice
12*627f7eb2Smrg  * is preserved.
13*627f7eb2Smrg  * ====================================================
14*627f7eb2Smrg  */
15*627f7eb2Smrg 
16*627f7eb2Smrg /* acoshq(x)
17*627f7eb2Smrg  * Method :
18*627f7eb2Smrg  *	Based on
19*627f7eb2Smrg  *		acoshl(x) = logq [ x + sqrtq(x*x-1) ]
20*627f7eb2Smrg  *	we have
21*627f7eb2Smrg  *		acoshl(x) := logq(x)+ln2,	if x is large; else
22*627f7eb2Smrg  *		acoshl(x) := logq(2x-1/(sqrtq(x*x-1)+x)) if x>2; else
23*627f7eb2Smrg  *		acoshl(x) := log1pq(t+sqrtq(2.0*t+t*t)); where t=x-1.
24*627f7eb2Smrg  *
25*627f7eb2Smrg  * Special cases:
26*627f7eb2Smrg  *	acoshl(x) is NaN with signal if x<1.
27*627f7eb2Smrg  *	acoshl(NaN) is NaN without signal.
28*627f7eb2Smrg  */
29*627f7eb2Smrg 
30*627f7eb2Smrg #include "quadmath-imp.h"
31*627f7eb2Smrg 
32*627f7eb2Smrg static const __float128
33*627f7eb2Smrg one	= 1.0,
34*627f7eb2Smrg ln2	= 0.6931471805599453094172321214581766Q;
35*627f7eb2Smrg 
36*627f7eb2Smrg __float128
acoshq(__float128 x)37*627f7eb2Smrg acoshq(__float128 x)
38*627f7eb2Smrg {
39*627f7eb2Smrg 	__float128 t;
40*627f7eb2Smrg 	uint64_t lx;
41*627f7eb2Smrg 	int64_t hx;
42*627f7eb2Smrg 	GET_FLT128_WORDS64(hx,lx,x);
43*627f7eb2Smrg 	if(hx<0x3fff000000000000LL) {		/* x < 1 */
44*627f7eb2Smrg 	    return (x-x)/(x-x);
45*627f7eb2Smrg 	} else if(hx >=0x4035000000000000LL) {	/* x > 2**54 */
46*627f7eb2Smrg 	    if(hx >=0x7fff000000000000LL) {	/* x is inf of NaN */
47*627f7eb2Smrg 		return x+x;
48*627f7eb2Smrg 	    } else
49*627f7eb2Smrg 		return logq(x)+ln2;	/* acoshl(huge)=logq(2x) */
50*627f7eb2Smrg 	} else if(((hx-0x3fff000000000000LL)|lx)==0) {
51*627f7eb2Smrg 	    return 0;			/* acosh(1) = 0 */
52*627f7eb2Smrg 	} else if (hx > 0x4000000000000000LL) {	/* 2**28 > x > 2 */
53*627f7eb2Smrg 	    t=x*x;
54*627f7eb2Smrg 	    return logq(2*x-one/(x+sqrtq(t-one)));
55*627f7eb2Smrg 	} else {			/* 1<x<2 */
56*627f7eb2Smrg 	    t = x-one;
57*627f7eb2Smrg 	    return log1pq(t+sqrtq(2*t+t*t));
58*627f7eb2Smrg 	}
59*627f7eb2Smrg }
60