Leaked source code of windows server 2003
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.

136 lines
3.0 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. log.c
  5. Abstract:
  6. logarithmic functions
  7. Author:
  8. Revision History:
  9. 29-sept-1999 ATM Shafiqul Khalid [askhalid] copied from rtl library.
  10. --*/
  11. #include <math.h>
  12. #include <trans.h>
  13. static double _log_hlp( double x, int flag);
  14. /* constants */
  15. static double const c0 = 0.70710678118654752440; /* sqrt(0.5) */
  16. static double const c1 = 0.69335937500000000000;
  17. static double const c2 = -2.121944400546905827679e-4;
  18. static double const c3 = 0.43429448190325182765;
  19. /* coefficients for rational approximation */
  20. static double const a0 = -0.64124943423745581147e2 ;
  21. static double const a1 = 0.16383943563021534222e2 ;
  22. static double const a2 = -0.78956112887491257267e0 ;
  23. static double const b0 = -0.76949932108494879777e3 ;
  24. static double const b1 = 0.31203222091924532844e3 ;
  25. static double const b2 = -0.35667977739034646171e2 ;
  26. /* b3=1.0 is not used -avoid multiplication by 1.0 */
  27. #define A(w) (((w) * a2 + a1) * (w) + a0)
  28. #define B(w) ((((w) + b2) * (w) + b1) * (w) + b0)
  29. /***
  30. *double log(double x) - natural logarithm
  31. *double log10(double x) - base-10 logarithm
  32. *
  33. *Purpose:
  34. * Compute the natural and base-10 logarithm of a number.
  35. * The algorithm (reduction / rational approximation) is
  36. * taken from Cody & Waite.
  37. *
  38. *Entry:
  39. *
  40. *Exit:
  41. *
  42. *Exceptions:
  43. * I P Z
  44. *******************************************************************************/
  45. double Proxylog10(double x)
  46. {
  47. return(_log_hlp(x,OP_LOG10));
  48. }
  49. double Proxylog(double x)
  50. {
  51. return(_log_hlp(x,OP_LOG));
  52. }
  53. static double _log_hlp(double x, int opcode)
  54. {
  55. unsigned int savedcw;
  56. int n;
  57. double f,result;
  58. double z,w,znum,zden;
  59. double rz,rzsq;
  60. /* save user fp control word */
  61. savedcw = _maskfp();
  62. /* check for infinity or NAN */
  63. if (IS_D_SPECIAL(x)){
  64. switch (_sptype(x)) {
  65. case T_PINF:
  66. RETURN(savedcw, x);
  67. case T_QNAN:
  68. return _handle_qnan1(opcode, x, savedcw);
  69. case T_SNAN:
  70. return _except1(FP_I, opcode, x, _s2qnan(x), savedcw);
  71. }
  72. /* NINF will be handled in the x<0 case */
  73. }
  74. if (x <= 0.0) {
  75. double qnan;
  76. if (x == 0.0) {
  77. return _except1(FP_Z,opcode,x,-D_INF,savedcw);
  78. }
  79. qnan = (opcode == OP_LOG ? QNAN_LOG : QNAN_LOG10);
  80. return _except1(FP_I,opcode,x,qnan,savedcw);
  81. }
  82. if (x == 1.0) {
  83. // no precision ecxeption
  84. RETURN(savedcw, 0.0);
  85. }
  86. f = _decomp(x, &n);
  87. if (f > c0) {
  88. znum = (f - 0.5) - 0.5;
  89. zden = f * 0.5 + 0.5;
  90. }
  91. else {
  92. n--;
  93. znum = f - 0.5;
  94. zden = znum * 0.5 + 0.5;
  95. }
  96. z = znum / zden;
  97. w = z * z;
  98. rzsq = w * A(w)/B(w) ;
  99. rz = z + z*rzsq;
  100. result = (n * c2 + rz) + n * c1;
  101. if (opcode == OP_LOG10) {
  102. result *= c3;
  103. }
  104. RETURN_INEXACT1(opcode,x,result,savedcw);
  105. }