1 #include "libm.h"
2 
tanhf(float x)3 float tanhf(float x)
4 {
5 	union {float f; uint32_t i;} u = {.f = x};
6 	uint32_t w;
7 	int sign;
8 	float t;
9 
10 	/* x = |x| */
11 	sign = u.i >> 31;
12 	u.i &= 0x7fffffff;
13 	x = u.f;
14 	w = u.i;
15 
16 	if (w > 0x3f0c9f54) {
17 		/* |x| > log(3)/2 ~= 0.5493 or nan */
18 		if (w > 0x41200000) {
19 			/* |x| > 10 */
20 			t = 1 + 0/x;
21 		} else {
22 			t = expm1f(2*x);
23 			t = 1 - 2/(t+2);
24 		}
25 	} else if (w > 0x3e82c578) {
26 		/* |x| > log(5/3)/2 ~= 0.2554 */
27 		t = expm1f(2*x);
28 		t = t/(t+2);
29 	} else if (w >= 0x00800000) {
30 		/* |x| >= 0x1p-126 */
31 		t = expm1f(-2*x);
32 		t = -t/(t+2);
33 	} else {
34 		/* |x| is subnormal */
35 		FORCE_EVAL(x*x);
36 		t = x;
37 	}
38 	return sign ? -t : t;
39 }
40