Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.5 KiB

  1. /* _LExp function */
  2. #include "xmath.h"
  3. _STD_BEGIN
  4. /* coefficients */
  5. #if _DLONG <= 1 /* assume IEEE 754 10 byte */
  6. static const long double p[] = { /* courtesy Dr. Tim Prince */
  7. 42.038913947607355L,
  8. 10096.353102778762831L,
  9. 333228.767219512631062L};
  10. static const long double q[] = { /* courtesy Dr. Tim Prince */
  11. 1.0L,
  12. 841.167880526530790L,
  13. 75730.834075476293976L,
  14. 666457.534439025262146L};
  15. #else /* assume IEEE 754 16 byte */
  16. static const long double p[] = { /* courtesy Dr. Tim Prince */
  17. 2.9807566520819951922553427799e-12L,
  18. 1.77137207816625148450390487465e-8L,
  19. 1.5047926518149448268177793026372e-5L,
  20. 3.611828913847589925056132680618007e-3L,
  21. 2.3684088648142335389097476188945590e-1L};
  22. static const long double q[] = { /* courtesy Dr. Tim Prince */
  23. 3.279723985560247033712687707263e-10L,
  24. 6.1415060072086450089090888123384e-7L,
  25. 2.708775201978218837374512615596512e-4L,
  26. 3.5087109907378343612154047611394786e-2L};
  27. #endif
  28. static const long double c1 = (22713.0L / 32768.0L);
  29. static const long double c2 = 1.4286068203094172321214581765680755e-6L;
  30. static const long double hugexp = LHUGE_EXP;
  31. static const long double invln2 = 1.4426950408889634073599246810018921L;
  32. _CRTIMP2 short __cdecl _LExp(long double *px, long double y, short eoff)
  33. { /* compute y*e^(*px), (*px) finite, |y| not huge */
  34. if (*px < -hugexp || y == 0.0L)
  35. { /* certain underflow */
  36. *px = 0.0L;
  37. return (0);
  38. }
  39. else if (hugexp < *px)
  40. { /* certain overflow */
  41. *px = _LInf._Long_double;
  42. return (_INFCODE);
  43. }
  44. else
  45. { /* xexp won't overflow */
  46. long double g = *px * invln2;
  47. short xexp = (short)(g + (g < 0 ? - 0.5L : + 0.5L));
  48. g = xexp;
  49. g = (*px - g * c1) - g * c2;
  50. if (-_LEps._Long_double < g && g < _LEps._Long_double)
  51. *px = y;
  52. else
  53. { /* g*g worth computing */
  54. #if _DLONG <= 1 /* assume IEEE 754 10 byte */
  55. const long double z = g * g;
  56. const long double w = ((z + q[1]) * z + q[2]) * z + q[3];
  57. g *= (p[0] * z + p[1]) * z + p[2];
  58. *px = (w + g) / (w - g) * 2.0L * y;
  59. --xexp;
  60. #else /* assume IEEE 754 16 byte */
  61. const long double z = g * g;
  62. const long double w = ((q[0] * z + q[1]) * z + q[2]) * z + q[3];
  63. const long double v = (((p[0] * z + p[1]) * z + p[2])
  64. * z + p[3]) * z + p[4];
  65. const long double u = g * w - v;
  66. *px = g * (g + z * (w + w + u)) / (2.0L - (g + z * u)) + g + 1.0;
  67. *px *= y;
  68. #endif
  69. }
  70. return (_LDscale(px, (long)xexp + eoff));
  71. }
  72. }
  73. _STD_END
  74. /*
  75. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  76. * Consult your license regarding permissions and restrictions.
  77. V3.10:0009 */