xref: /openbsd-src/lib/libm/src/e_acosh.c (revision 2f2c00629eff6a304ebffb255fc56f4fa7a1833b)
1df930be7Sderaadt /* @(#)e_acosh.c 5.1 93/09/24 */
2df930be7Sderaadt /*
3df930be7Sderaadt  * ====================================================
4df930be7Sderaadt  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5df930be7Sderaadt  *
6df930be7Sderaadt  * Developed at SunPro, a Sun Microsystems, Inc. business.
7df930be7Sderaadt  * Permission to use, copy, modify, and distribute this
8df930be7Sderaadt  * software is freely granted, provided that this notice
9df930be7Sderaadt  * is preserved.
10df930be7Sderaadt  * ====================================================
11df930be7Sderaadt  */
12df930be7Sderaadt 
137b36286aSmartynas /* acosh(x)
14df930be7Sderaadt  * Method :
15df930be7Sderaadt  *	Based on
16df930be7Sderaadt  *		acosh(x) = log [ x + sqrt(x*x-1) ]
17df930be7Sderaadt  *	we have
18df930be7Sderaadt  *		acosh(x) := log(x)+ln2,	if x is large; else
19df930be7Sderaadt  *		acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
20df930be7Sderaadt  *		acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
21df930be7Sderaadt  *
22df930be7Sderaadt  * Special cases:
23df930be7Sderaadt  *	acosh(x) is NaN with signal if x<1.
24df930be7Sderaadt  *	acosh(NaN) is NaN without signal.
25df930be7Sderaadt  */
26df930be7Sderaadt 
2749393c00Smartynas #include <float.h>
2849393c00Smartynas #include <math.h>
2949393c00Smartynas 
30df930be7Sderaadt #include "math_private.h"
31df930be7Sderaadt 
32df930be7Sderaadt static const double
33df930be7Sderaadt one	= 1.0,
34df930be7Sderaadt ln2	= 6.93147180559945286227e-01;  /* 0x3FE62E42, 0xFEFA39EF */
35df930be7Sderaadt 
36e7beb4a7Smillert double
acosh(double x)377b36286aSmartynas acosh(double x)
38df930be7Sderaadt {
39df930be7Sderaadt 	double t;
40df930be7Sderaadt 	int32_t hx;
41df930be7Sderaadt 	u_int32_t lx;
42df930be7Sderaadt 	EXTRACT_WORDS(hx,lx,x);
43df930be7Sderaadt 	if(hx<0x3ff00000) {		/* x < 1 */
44df930be7Sderaadt 	    return (x-x)/(x-x);
45df930be7Sderaadt 	} else if(hx >=0x41b00000) {	/* x > 2**28 */
46df930be7Sderaadt 	    if(hx >=0x7ff00000) {	/* x is inf of NaN */
47df930be7Sderaadt 	        return x+x;
48df930be7Sderaadt 	    } else
497b36286aSmartynas 		return log(x)+ln2;	/* acosh(huge)=log(2x) */
50df930be7Sderaadt 	} else if(((hx-0x3ff00000)|lx)==0) {
51df930be7Sderaadt 	    return 0.0;			/* acosh(1) = 0 */
52df930be7Sderaadt 	} else if (hx > 0x40000000) {	/* 2**28 > x > 2 */
53df930be7Sderaadt 	    t=x*x;
547b36286aSmartynas 	    return log(2.0*x-one/(x+sqrt(t-one)));
55df930be7Sderaadt 	} else {			/* 1<x<2 */
56df930be7Sderaadt 	    t = x-one;
57df930be7Sderaadt 	    return log1p(t+sqrt(2.0*t+t*t));
58df930be7Sderaadt 	}
59df930be7Sderaadt }
60*2f2c0062Sguenther DEF_STD(acosh);
61*2f2c0062Sguenther LDBL_MAYBE_UNUSED_CLONE(acosh);
62