cos.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Cosine function of numerical and symbolic arguments
  2. #include "stdafx.h"
  3. #include "defs.h"
  4. void
  5. eval_cos(void)
  6. {
  7. push(cadr(p1));
  8. eval();
  9. cosine();
  10. }
  11. void
  12. cosine(void)
  13. {
  14. save();
  15. p1 = pop();
  16. if (car(p1) == symbol(ADD))
  17. cosine_of_angle_sum();
  18. else
  19. cosine_of_angle();
  20. restore();
  21. }
  22. // Use angle sum formula for special angles.
  23. #define A p3
  24. #define B p4
  25. void
  26. cosine_of_angle_sum(void)
  27. {
  28. p2 = cdr(p1);
  29. while (iscons(p2)) {
  30. B = car(p2);
  31. if (isnpi(B)) {
  32. push(p1);
  33. push(B);
  34. subtract();
  35. A = pop();
  36. push(A);
  37. cosine();
  38. push(B);
  39. cosine();
  40. multiply();
  41. push(A);
  42. sine();
  43. push(B);
  44. sine();
  45. multiply();
  46. subtract();
  47. return;
  48. }
  49. p2 = cdr(p2);
  50. }
  51. cosine_of_angle();
  52. }
  53. void
  54. cosine_of_angle(void)
  55. {
  56. int n;
  57. double d;
  58. if (car(p1) == symbol(ARCCOS)) {
  59. push(cadr(p1));
  60. return;
  61. }
  62. if (isdouble(p1)) {
  63. d = cos(p1->u.d);
  64. if (fabs(d) < 1e-10)
  65. d = 0.0;
  66. push_double(d);
  67. return;
  68. }
  69. // cosine function is symmetric, cos(-x) = cos(x)
  70. if (isnegative(p1)) {
  71. push(p1);
  72. negate();
  73. p1 = pop();
  74. }
  75. // cos(arctan(x)) = 1 / sqrt(1 + x^2)
  76. // see p. 173 of the CRC Handbook of Mathematical Sciences
  77. if (car(p1) == symbol(ARCTAN)) {
  78. push_integer(1);
  79. push(cadr(p1));
  80. push_integer(2);
  81. power();
  82. add();
  83. push_rational(-1, 2);
  84. power();
  85. return;
  86. }
  87. // multiply by 180/pi
  88. push(p1);
  89. push_integer(180);
  90. multiply();
  91. push_symbol(PI);
  92. divide();
  93. n = pop_integer();
  94. if (n < 0) {
  95. push(symbol(COS));
  96. push(p1);
  97. list(2);
  98. return;
  99. }
  100. switch (n % 360) {
  101. case 90:
  102. case 270:
  103. push_integer(0);
  104. break;
  105. case 60:
  106. case 300:
  107. push_rational(1, 2);
  108. break;
  109. case 120:
  110. case 240:
  111. push_rational(-1, 2);
  112. break;
  113. case 45:
  114. case 315:
  115. push_rational(1, 2);
  116. push_integer(2);
  117. push_rational(1, 2);
  118. power();
  119. multiply();
  120. break;
  121. case 135:
  122. case 225:
  123. push_rational(-1, 2);
  124. push_integer(2);
  125. push_rational(1, 2);
  126. power();
  127. multiply();
  128. break;
  129. case 30:
  130. case 330:
  131. push_rational(1, 2);
  132. push_integer(3);
  133. push_rational(1, 2);
  134. power();
  135. multiply();
  136. break;
  137. case 150:
  138. case 210:
  139. push_rational(-1, 2);
  140. push_integer(3);
  141. push_rational(1, 2);
  142. power();
  143. multiply();
  144. break;
  145. case 0:
  146. push_integer(1);
  147. break;
  148. case 180:
  149. push_integer(-1);
  150. break;
  151. default:
  152. push(symbol(COS));
  153. push(p1);
  154. list(2);
  155. break;
  156. }
  157. }