log.cpp 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // natural logarithm
  2. #include "stdafx.h"
  3. #include "defs.h"
  4. void
  5. eval_log(void)
  6. {
  7. push(cadr(p1));
  8. eval();
  9. logarithm();
  10. }
  11. void
  12. logarithm(void)
  13. {
  14. save();
  15. yylog();
  16. restore();
  17. }
  18. void
  19. yylog(void)
  20. {
  21. double d;
  22. p1 = pop();
  23. if (p1 == symbol(E)) {
  24. push_integer(1);
  25. return;
  26. }
  27. if (equaln(p1, 1)) {
  28. push_integer(0);
  29. return;
  30. }
  31. if (isnegativenumber(p1)) {
  32. push(p1);
  33. negate();
  34. logarithm();
  35. push(imaginaryunit);
  36. push_symbol(PI);
  37. multiply();
  38. add();
  39. return;
  40. }
  41. if (isdouble(p1)) {
  42. d = log(p1->u.d);
  43. push_double(d);
  44. return;
  45. }
  46. // rational number and not an integer?
  47. if (isfraction(p1)) {
  48. push(p1);
  49. numerator();
  50. logarithm();
  51. push(p1);
  52. denominator();
  53. logarithm();
  54. subtract();
  55. return;
  56. }
  57. // log(a ^ b) --> b log(a)
  58. if (car(p1) == symbol(POWER)) {
  59. push(caddr(p1));
  60. push(cadr(p1));
  61. logarithm();
  62. multiply();
  63. return;
  64. }
  65. // log(a * b) --> log(a) + log(b)
  66. if (car(p1) == symbol(MULTIPLY)) {
  67. push_integer(0);
  68. p1 = cdr(p1);
  69. while (iscons(p1)) {
  70. push(car(p1));
  71. logarithm();
  72. add();
  73. p1 = cdr(p1);
  74. }
  75. return;
  76. }
  77. push_symbol(LOG);
  78. push(p1);
  79. list(2);
  80. }