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.

299 lines
6.4 KiB

  1. //----------------------------------------------------------------------------
  2. // File trans.c
  3. // Author Timothy David Corrie Jr. ([email protected])
  4. // Copyright (C) 1995-96 Microsoft
  5. // Date 01-16-95
  6. //
  7. //
  8. // Description
  9. //
  10. // Contains sin, cos and tan for rationals
  11. //
  12. //
  13. //----------------------------------------------------------------------------
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #if defined( DOS )
  18. #include <dosstub.h>
  19. #else
  20. #include <windows.h>
  21. #endif
  22. #include <ratpak.h>
  23. void scalerat( IN OUT PRAT *pa, IN ANGLE_TYPE angletype )
  24. {
  25. switch ( angletype )
  26. {
  27. case ANGLE_RAD:
  28. scale2pi( pa );
  29. break;
  30. case ANGLE_DEG:
  31. scale( pa, rat_360 );
  32. break;
  33. case ANGLE_GRAD:
  34. scale( pa, rat_400 );
  35. break;
  36. }
  37. }
  38. //-----------------------------------------------------------------------------
  39. //
  40. // FUNCTION: sinrat, _sinrat
  41. //
  42. // ARGUMENTS: x PRAT representation of number to take the sine of
  43. //
  44. // RETURN: sin of x in PRAT form.
  45. //
  46. // EXPLANATION: This uses Taylor series
  47. //
  48. // n
  49. // ___ 2j+1 j
  50. // \ ] X -1
  51. // \ ---------
  52. // / (2j+1)!
  53. // /__]
  54. // j=0
  55. // or,
  56. // n
  57. // ___ 2
  58. // \ ] -X
  59. // \ thisterm ; where thisterm = thisterm * ---------
  60. // / j j+1 j (2j)*(2j+1)
  61. // /__]
  62. // j=0
  63. //
  64. // thisterm = X ; and stop when thisterm < precision used.
  65. // 0 n
  66. //
  67. //-----------------------------------------------------------------------------
  68. void _sinrat( PRAT *px )
  69. {
  70. CREATETAYLOR();
  71. DUPRAT(pret,*px);
  72. DUPRAT(thisterm,*px);
  73. DUPNUM(n2,num_one);
  74. xx->pp->sign *= -1;
  75. do {
  76. NEXTTERM(xx,INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2));
  77. } while ( !SMALL_ENOUGH_RAT( thisterm ) );
  78. DESTROYTAYLOR();
  79. // Since *px might be epsilon above 1 or below -1, due to TRIMIT we need
  80. // this trick here.
  81. inbetween(px,rat_one);
  82. // Since *px might be epsilon near zero we must set it to zero.
  83. if ( rat_le(*px,rat_smallest) && rat_ge(*px,rat_negsmallest) )
  84. {
  85. DUPRAT(*px,rat_zero);
  86. }
  87. }
  88. void sinrat( PRAT *px )
  89. {
  90. scale2pi(px);
  91. _sinrat(px);
  92. }
  93. void sinanglerat( IN OUT PRAT *pa, IN ANGLE_TYPE angletype )
  94. {
  95. scalerat( pa, angletype );
  96. switch ( angletype )
  97. {
  98. case ANGLE_DEG:
  99. if ( rat_gt( *pa, rat_180 ) )
  100. {
  101. subrat(pa,rat_360);
  102. }
  103. divrat( pa, rat_180 );
  104. mulrat( pa, pi );
  105. break;
  106. case ANGLE_GRAD:
  107. if ( rat_gt( *pa, rat_200 ) )
  108. {
  109. subrat(pa,rat_400);
  110. }
  111. divrat( pa, rat_200 );
  112. mulrat( pa, pi );
  113. break;
  114. }
  115. _sinrat( pa );
  116. }
  117. //-----------------------------------------------------------------------------
  118. //
  119. // FUNCTION: cosrat, _cosrat
  120. //
  121. // ARGUMENTS: x PRAT representation of number to take the cosine of
  122. //
  123. // RETURN: cosin of x in PRAT form.
  124. //
  125. // EXPLANATION: This uses Taylor series
  126. //
  127. // n
  128. // ___ 2j j
  129. // \ ] X -1
  130. // \ ---------
  131. // / (2j)!
  132. // /__]
  133. // j=0
  134. // or,
  135. // n
  136. // ___ 2
  137. // \ ] -X
  138. // \ thisterm ; where thisterm = thisterm * ---------
  139. // / j j+1 j (2j)*(2j+1)
  140. // /__]
  141. // j=0
  142. //
  143. // thisterm = 1 ; and stop when thisterm < precision used.
  144. // 0 n
  145. //
  146. //-----------------------------------------------------------------------------
  147. void _cosrat( PRAT *px )
  148. {
  149. CREATETAYLOR();
  150. pret->pp=longtonum( 1L, nRadix );
  151. pret->pq=longtonum( 1L, nRadix );
  152. DUPRAT(thisterm,pret)
  153. n2=longtonum(0L, nRadix);
  154. xx->pp->sign *= -1;
  155. do {
  156. NEXTTERM(xx,INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2));
  157. } while ( !SMALL_ENOUGH_RAT( thisterm ) );
  158. DESTROYTAYLOR();
  159. // Since *px might be epsilon above 1 or below -1, due to TRIMIT we need
  160. // this trick here.
  161. inbetween(px,rat_one);
  162. // Since *px might be epsilon near zero we must set it to zero.
  163. if ( rat_le(*px,rat_smallest) && rat_ge(*px,rat_negsmallest) )
  164. {
  165. DUPRAT(*px,rat_zero);
  166. }
  167. }
  168. void cosrat( PRAT *px )
  169. {
  170. scale2pi(px);
  171. _cosrat(px);
  172. }
  173. void cosanglerat( IN OUT PRAT *pa, IN ANGLE_TYPE angletype )
  174. {
  175. scalerat( pa, angletype );
  176. switch ( angletype )
  177. {
  178. case ANGLE_DEG:
  179. if ( rat_gt( *pa, rat_180 ) )
  180. {
  181. PRAT ptmp=NULL;
  182. DUPRAT(ptmp,rat_360);
  183. subrat(&ptmp,*pa);
  184. destroyrat(*pa);
  185. *pa=ptmp;
  186. }
  187. divrat( pa, rat_180 );
  188. mulrat( pa, pi );
  189. break;
  190. case ANGLE_GRAD:
  191. if ( rat_gt( *pa, rat_200 ) )
  192. {
  193. PRAT ptmp=NULL;
  194. DUPRAT(ptmp,rat_400);
  195. subrat(&ptmp,*pa);
  196. destroyrat(*pa);
  197. *pa=ptmp;
  198. }
  199. divrat( pa, rat_200 );
  200. mulrat( pa, pi );
  201. break;
  202. }
  203. _cosrat( pa );
  204. }
  205. //-----------------------------------------------------------------------------
  206. //
  207. // FUNCTION: tanrat, _tanrat
  208. //
  209. // ARGUMENTS: x PRAT representation of number to take the tangent of
  210. //
  211. // RETURN: tan of x in PRAT form.
  212. //
  213. // EXPLANATION: This uses sinrat and cosrat
  214. //
  215. //-----------------------------------------------------------------------------
  216. void _tanrat( PRAT *px )
  217. {
  218. PRAT ptmp=NULL;
  219. DUPRAT(ptmp,*px);
  220. _sinrat(px);
  221. _cosrat(&ptmp);
  222. if ( zerrat( ptmp ) )
  223. {
  224. destroyrat(ptmp);
  225. throw( CALC_E_DOMAIN );
  226. }
  227. divrat(px,ptmp);
  228. destroyrat(ptmp);
  229. }
  230. void tanrat( PRAT *px )
  231. {
  232. scale2pi(px);
  233. _tanrat(px);
  234. }
  235. void tananglerat( IN OUT PRAT *pa, IN ANGLE_TYPE angletype )
  236. {
  237. scalerat( pa, angletype );
  238. switch ( angletype )
  239. {
  240. case ANGLE_DEG:
  241. if ( rat_gt( *pa, rat_180 ) )
  242. {
  243. subrat(pa,rat_180);
  244. }
  245. divrat( pa, rat_180 );
  246. mulrat( pa, pi );
  247. break;
  248. case ANGLE_GRAD:
  249. if ( rat_gt( *pa, rat_200 ) )
  250. {
  251. subrat(pa,rat_200);
  252. }
  253. divrat( pa, rat_200 );
  254. mulrat( pa, pi );
  255. break;
  256. }
  257. _tanrat( pa );
  258. }