1#include "libm.h"
2
3float 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