xref: /aosp_15_r20/external/musl/src/math/tanhl.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #include "libm.h"
2*c9945492SAndroid Build Coastguard Worker 
3*c9945492SAndroid Build Coastguard Worker #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
tanhl(long double x)4*c9945492SAndroid Build Coastguard Worker long double tanhl(long double x)
5*c9945492SAndroid Build Coastguard Worker {
6*c9945492SAndroid Build Coastguard Worker 	return tanh(x);
7*c9945492SAndroid Build Coastguard Worker }
8*c9945492SAndroid Build Coastguard Worker #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
tanhl(long double x)9*c9945492SAndroid Build Coastguard Worker long double tanhl(long double x)
10*c9945492SAndroid Build Coastguard Worker {
11*c9945492SAndroid Build Coastguard Worker 	union ldshape u = {x};
12*c9945492SAndroid Build Coastguard Worker 	unsigned ex = u.i.se & 0x7fff;
13*c9945492SAndroid Build Coastguard Worker 	unsigned sign = u.i.se & 0x8000;
14*c9945492SAndroid Build Coastguard Worker 	uint32_t w;
15*c9945492SAndroid Build Coastguard Worker 	long double t;
16*c9945492SAndroid Build Coastguard Worker 
17*c9945492SAndroid Build Coastguard Worker 	/* x = |x| */
18*c9945492SAndroid Build Coastguard Worker 	u.i.se = ex;
19*c9945492SAndroid Build Coastguard Worker 	x = u.f;
20*c9945492SAndroid Build Coastguard Worker 	w = u.i.m >> 32;
21*c9945492SAndroid Build Coastguard Worker 
22*c9945492SAndroid Build Coastguard Worker 	if (ex > 0x3ffe || (ex == 0x3ffe && w > 0x8c9f53d5)) {
23*c9945492SAndroid Build Coastguard Worker 		/* |x| > log(3)/2 ~= 0.5493 or nan */
24*c9945492SAndroid Build Coastguard Worker 		if (ex >= 0x3fff+5) {
25*c9945492SAndroid Build Coastguard Worker 			/* |x| >= 32 */
26*c9945492SAndroid Build Coastguard Worker 			t = 1 + 0/(x + 0x1p-120f);
27*c9945492SAndroid Build Coastguard Worker 		} else {
28*c9945492SAndroid Build Coastguard Worker 			t = expm1l(2*x);
29*c9945492SAndroid Build Coastguard Worker 			t = 1 - 2/(t+2);
30*c9945492SAndroid Build Coastguard Worker 		}
31*c9945492SAndroid Build Coastguard Worker 	} else if (ex > 0x3ffd || (ex == 0x3ffd && w > 0x82c577d4)) {
32*c9945492SAndroid Build Coastguard Worker 		/* |x| > log(5/3)/2 ~= 0.2554 */
33*c9945492SAndroid Build Coastguard Worker 		t = expm1l(2*x);
34*c9945492SAndroid Build Coastguard Worker 		t = t/(t+2);
35*c9945492SAndroid Build Coastguard Worker 	} else {
36*c9945492SAndroid Build Coastguard Worker 		/* |x| is small */
37*c9945492SAndroid Build Coastguard Worker 		t = expm1l(-2*x);
38*c9945492SAndroid Build Coastguard Worker 		t = -t/(t+2);
39*c9945492SAndroid Build Coastguard Worker 	}
40*c9945492SAndroid Build Coastguard Worker 	return sign ? -t : t;
41*c9945492SAndroid Build Coastguard Worker }
42*c9945492SAndroid Build Coastguard Worker #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
43*c9945492SAndroid Build Coastguard Worker // TODO: broken implementation to make things compile
tanhl(long double x)44*c9945492SAndroid Build Coastguard Worker long double tanhl(long double x)
45*c9945492SAndroid Build Coastguard Worker {
46*c9945492SAndroid Build Coastguard Worker 	return tanh(x);
47*c9945492SAndroid Build Coastguard Worker }
48*c9945492SAndroid Build Coastguard Worker #endif
49