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