| OLD | NEW |
| 1 #include "libm.h" | 1 #include "libm.h" |
| 2 | 2 |
| 3 /* cosh(x) = (exp(x) + 1/exp(x))/2 | 3 /* cosh(x) = (exp(x) + 1/exp(x))/2 |
| 4 * = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x) | 4 * = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x) |
| 5 * = 1 + x*x/2 + o(x^4) | 5 * = 1 + x*x/2 + o(x^4) |
| 6 */ | 6 */ |
| 7 double cosh(double x) | 7 double cosh(double x) { |
| 8 { | 8 union { |
| 9 » union {double f; uint64_t i;} u = {.f = x}; | 9 double f; |
| 10 » uint32_t w; | 10 uint64_t i; |
| 11 » double t; | 11 } u = {.f = x}; |
| 12 uint32_t w; |
| 13 double t; |
| 12 | 14 |
| 13 » /* |x| */ | 15 /* |x| */ |
| 14 » u.i &= (uint64_t)-1/2; | 16 u.i &= (uint64_t)-1 / 2; |
| 15 » x = u.f; | 17 x = u.f; |
| 16 » w = u.i >> 32; | 18 w = u.i >> 32; |
| 17 | 19 |
| 18 » /* |x| < log(2) */ | 20 /* |x| < log(2) */ |
| 19 » if (w < 0x3fe62e42) { | 21 if (w < 0x3fe62e42) { |
| 20 » » if (w < 0x3ff00000 - (26<<20)) { | 22 if (w < 0x3ff00000 - (26 << 20)) { |
| 21 » » » /* raise inexact if x!=0 */ | 23 /* raise inexact if x!=0 */ |
| 22 » » » FORCE_EVAL(x + 0x1p120f); | 24 FORCE_EVAL(x + 0x1p120f); |
| 23 » » » return 1; | 25 return 1; |
| 24 » » } | 26 } |
| 25 » » t = expm1(x); | 27 t = expm1(x); |
| 26 » » return 1 + t*t/(2*(1+t)); | 28 return 1 + t * t / (2 * (1 + t)); |
| 27 » } | 29 } |
| 28 | 30 |
| 29 » /* |x| < log(DBL_MAX) */ | 31 /* |x| < log(DBL_MAX) */ |
| 30 » if (w < 0x40862e42) { | 32 if (w < 0x40862e42) { |
| 31 » » t = exp(x); | 33 t = exp(x); |
| 32 » » /* note: if x>log(0x1p26) then the 1/t is not needed */ | 34 /* note: if x>log(0x1p26) then the 1/t is not needed */ |
| 33 » » return 0.5*(t + 1/t); | 35 return 0.5 * (t + 1 / t); |
| 34 » } | 36 } |
| 35 | 37 |
| 36 » /* |x| > log(DBL_MAX) or nan */ | 38 /* |x| > log(DBL_MAX) or nan */ |
| 37 » /* note: the result is stored to handle overflow */ | 39 /* note: the result is stored to handle overflow */ |
| 38 » t = __expo2(x); | 40 t = __expo2(x); |
| 39 » return t; | 41 return t; |
| 40 } | 42 } |
| OLD | NEW |