xref: /aosp_15_r20/external/musl/src/math/acosh.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #include "libm.h"
2*c9945492SAndroid Build Coastguard Worker 
3*c9945492SAndroid Build Coastguard Worker #if FLT_EVAL_METHOD==2
4*c9945492SAndroid Build Coastguard Worker #undef sqrt
5*c9945492SAndroid Build Coastguard Worker #define sqrt sqrtl
6*c9945492SAndroid Build Coastguard Worker #endif
7*c9945492SAndroid Build Coastguard Worker 
8*c9945492SAndroid Build Coastguard Worker /* acosh(x) = log(x + sqrt(x*x-1)) */
acosh(double x)9*c9945492SAndroid Build Coastguard Worker double acosh(double x)
10*c9945492SAndroid Build Coastguard Worker {
11*c9945492SAndroid Build Coastguard Worker 	union {double f; uint64_t i;} u = {.f = x};
12*c9945492SAndroid Build Coastguard Worker 	unsigned e = u.i >> 52 & 0x7ff;
13*c9945492SAndroid Build Coastguard Worker 
14*c9945492SAndroid Build Coastguard Worker 	/* x < 1 domain error is handled in the called functions */
15*c9945492SAndroid Build Coastguard Worker 
16*c9945492SAndroid Build Coastguard Worker 	if (e < 0x3ff + 1)
17*c9945492SAndroid Build Coastguard Worker 		/* |x| < 2, up to 2ulp error in [1,1.125] */
18*c9945492SAndroid Build Coastguard Worker 		return log1p(x-1 + sqrt((x-1)*(x-1)+2*(x-1)));
19*c9945492SAndroid Build Coastguard Worker 	if (e < 0x3ff + 26)
20*c9945492SAndroid Build Coastguard Worker 		/* |x| < 0x1p26 */
21*c9945492SAndroid Build Coastguard Worker 		return log(2*x - 1/(x+sqrt(x*x-1)));
22*c9945492SAndroid Build Coastguard Worker 	/* |x| >= 0x1p26 or nan */
23*c9945492SAndroid Build Coastguard Worker 	return log(x) + 0.693147180559945309417232121458176568;
24*c9945492SAndroid Build Coastguard Worker }
25