log.c 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*
  2. log returns the natural logarithm of its floating
  3. point argument.
  4. The coefficients are #2705 from Hart & Cheney. (19.38D)
  5. It calls frexp.
  6. */
  7. #include <u.h>
  8. #include <libc.h>
  9. #define log2 0.693147180559945309e0
  10. #define ln10o1 .4342944819032518276511
  11. #define sqrto2 0.707106781186547524e0
  12. #define p0 -.240139179559210510e2
  13. #define p1 0.309572928215376501e2
  14. #define p2 -.963769093377840513e1
  15. #define p3 0.421087371217979714e0
  16. #define q0 -.120069589779605255e2
  17. #define q1 0.194809660700889731e2
  18. #define q2 -.891110902798312337e1
  19. double
  20. log(double arg)
  21. {
  22. double x, z, zsq, temp;
  23. int exp;
  24. if(arg <= 0)
  25. return NaN();
  26. x = frexp(arg, &exp);
  27. while(x < 0.5) {
  28. x *= 2;
  29. exp--;
  30. }
  31. if(x < sqrto2) {
  32. x *= 2;
  33. exp--;
  34. }
  35. z = (x-1) / (x+1);
  36. zsq = z*z;
  37. temp = ((p3*zsq + p2)*zsq + p1)*zsq + p0;
  38. temp = temp/(((zsq + q2)*zsq + q1)*zsq + q0);
  39. temp = temp*z + exp*log2;
  40. return temp;
  41. }
  42. double
  43. log10(double arg)
  44. {
  45. if(arg <= 0)
  46. return NaN();
  47. return log(arg) * ln10o1;
  48. }