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