fast_exp.h 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. /* A fast approximation of the exponential function.
  2. * Reference [1]: https://schraudolph.org/pubs/Schraudolph99.pdf
  3. * Reference [2]: https://doi.org/10.1162/089976600300015033
  4. * Additional improvements by Leonid Bloch. */
  5. #include <stdint.h>
  6. /* use just EXP_A = 1512775 for integer version, to avoid FP calculations */
  7. #define EXP_A (1512775.3951951856938) /* 2^20/ln2 */
  8. /* For min. RMS error */
  9. #define EXP_BC 1072632447 /* 1023*2^20 - 60801 */
  10. /* For min. max. relative error */
  11. /* #define EXP_BC 1072647449 */ /* 1023*2^20 - 45799 */
  12. /* For min. mean relative error */
  13. /* #define EXP_BC 1072625005 */ /* 1023*2^20 - 68243 */
  14. __inline double _fast_exp (double y)
  15. {
  16. union
  17. {
  18. double d;
  19. struct { int32_t i, j; } n;
  20. char t[8];
  21. } _eco;
  22. _eco.n.i = 1;
  23. switch(_eco.t[0]) {
  24. case 1:
  25. /* Little endian */
  26. _eco.n.j = (int32_t)(EXP_A*(y)) + EXP_BC;
  27. _eco.n.i = 0;
  28. break;
  29. case 0:
  30. /* Big endian */
  31. _eco.n.i = (int32_t)(EXP_A*(y)) + EXP_BC;
  32. _eco.n.j = 0;
  33. break;
  34. }
  35. return _eco.d;
  36. }
  37. __inline float _fast_expf (float y)
  38. {
  39. return (float)_fast_exp((double)y);
  40. }