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