xref: /inferno-os/libmath/fdlibm/e_acosh.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth /* derived from /netlib/fdlibm */
2*37da2899SCharles.Forsyth 
3*37da2899SCharles.Forsyth /* @(#)e_acosh.c 1.3 95/01/18 */
4*37da2899SCharles.Forsyth /*
5*37da2899SCharles.Forsyth  * ====================================================
6*37da2899SCharles.Forsyth  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
7*37da2899SCharles.Forsyth  *
8*37da2899SCharles.Forsyth  * Developed at SunSoft, a Sun Microsystems, Inc. business.
9*37da2899SCharles.Forsyth  * Permission to use, copy, modify, and distribute this
10*37da2899SCharles.Forsyth  * software is freely granted, provided that this notice
11*37da2899SCharles.Forsyth  * is preserved.
12*37da2899SCharles.Forsyth  * ====================================================
13*37da2899SCharles.Forsyth  *
14*37da2899SCharles.Forsyth  */
15*37da2899SCharles.Forsyth 
16*37da2899SCharles.Forsyth /* __ieee754_acosh(x)
17*37da2899SCharles.Forsyth  * Method :
18*37da2899SCharles.Forsyth  *	Based on
19*37da2899SCharles.Forsyth  *		acosh(x) = log [ x + sqrt(x*x-1) ]
20*37da2899SCharles.Forsyth  *	we have
21*37da2899SCharles.Forsyth  *		acosh(x) := log(x)+ln2,	if x is large; else
22*37da2899SCharles.Forsyth  *		acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
23*37da2899SCharles.Forsyth  *		acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
24*37da2899SCharles.Forsyth  *
25*37da2899SCharles.Forsyth  * Special cases:
26*37da2899SCharles.Forsyth  *	acosh(x) is NaN with signal if x<1.
27*37da2899SCharles.Forsyth  *	acosh(NaN) is NaN without signal.
28*37da2899SCharles.Forsyth  */
29*37da2899SCharles.Forsyth 
30*37da2899SCharles.Forsyth #include "fdlibm.h"
31*37da2899SCharles.Forsyth 
32*37da2899SCharles.Forsyth static const double
33*37da2899SCharles.Forsyth one	= 1.0,
34*37da2899SCharles.Forsyth ln2	= 6.93147180559945286227e-01;  /* 0x3FE62E42, 0xFEFA39EF */
35*37da2899SCharles.Forsyth 
__ieee754_acosh(double x)36*37da2899SCharles.Forsyth 	double __ieee754_acosh(double x)
37*37da2899SCharles.Forsyth {
38*37da2899SCharles.Forsyth 	double t;
39*37da2899SCharles.Forsyth 	int hx;
40*37da2899SCharles.Forsyth 	hx = __HI(x);
41*37da2899SCharles.Forsyth 	if(hx<0x3ff00000) {		/* x < 1 */
42*37da2899SCharles.Forsyth 	    return (x-x)/(x-x);
43*37da2899SCharles.Forsyth 	} else if(hx >=0x41b00000) {	/* x > 2**28 */
44*37da2899SCharles.Forsyth 	    if(hx >=0x7ff00000) {	/* x is inf of NaN */
45*37da2899SCharles.Forsyth 	        return x+x;
46*37da2899SCharles.Forsyth 	    } else
47*37da2899SCharles.Forsyth 		return __ieee754_log(x)+ln2;	/* acosh(Huge)=log(2x) */
48*37da2899SCharles.Forsyth 	} else if(((hx-0x3ff00000)|__LO(x))==0) {
49*37da2899SCharles.Forsyth 	    return 0.0;			/* acosh(1) = 0 */
50*37da2899SCharles.Forsyth 	} else if (hx > 0x40000000) {	/* 2**28 > x > 2 */
51*37da2899SCharles.Forsyth 	    t=x*x;
52*37da2899SCharles.Forsyth 	    return __ieee754_log(2.0*x-one/(x+sqrt(t-one)));
53*37da2899SCharles.Forsyth 	} else {			/* 1<x<2 */
54*37da2899SCharles.Forsyth 	    t = x-one;
55*37da2899SCharles.Forsyth 	    return log1p(t+sqrt(2.0*t+t*t));
56*37da2899SCharles.Forsyth 	}
57*37da2899SCharles.Forsyth }
58