fastmath.red 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. module fastmath; % Definitions of key functions in the math module of
  2. % arith.red using C versions. This file should be
  3. % loaded into REDUCE before the math module is loaded.
  4. global '(!!deg2rad !!rad2deg !!floatbits);
  5. compiletime
  6. global '(!!fleps1exp !!plumaxexp !!pluminexp !!timmaxexp !!timminexp);
  7. symbolic smacro procedure degreestoradians x; times2(x,!!deg2rad);
  8. symbolic smacro procedure radianstodegrees x; times2(x,!!rad2deg);
  9. remflag('(sin cos tan sind cosd tand cotd secd cscd asin acos atan
  10. asecd acscd atan2d atan2 sqrt exp log hypot cosh sinh tanh),
  11. 'lose);
  12. % ***** REMOVE THE FOLLOWING LINE WHEN FLOAT.C/EXTERNALS.SL UPDATED.
  13. flag('(hypot cosh sinh tanh),'lose);
  14. % ***** REMOVE THE FOLLOWING LINE WHEN WE KNOW HOW TO HANDLE COMPLEX
  15. % VALUES FOR ACOS, ASIN.
  16. flag('(acos asin),'lose);
  17. % Trig functions in radians.
  18. symbolic procedure cos x;
  19. begin scalar result;
  20. x := float x; % We put this here to make sure no GC can happen
  21. % between gtfltn and mkfltn.
  22. result := gtfltn();
  23. uxcos(floatbase result,floatbase fltinf x);
  24. return mkfltn result
  25. end;
  26. symbolic procedure sin x;
  27. begin scalar result;
  28. x := float x;
  29. result := gtfltn();
  30. uxsin(floatbase result,floatbase fltinf x);
  31. return mkfltn result
  32. end;
  33. symbolic procedure tan x;
  34. begin scalar result;
  35. x := float x;
  36. result := gtfltn();
  37. uxtan(floatbase result,floatbase fltinf x);
  38. return mkfltn result
  39. end;
  40. symbolic procedure acos x;
  41. begin scalar result;
  42. if abs x> 1.0
  43. then error(99,list("argument to ACOS too large:",x));
  44. x := float x;
  45. result := gtfltn();
  46. uxacos(floatbase result,floatbase fltinf x);
  47. return mkfltn result
  48. end;
  49. symbolic procedure asin x;
  50. begin scalar result;
  51. if abs x> 1.0
  52. then error(99,list("argument to ASIN too large:",x));
  53. x := float x;
  54. result := gtfltn();
  55. uxasin(floatbase result,floatbase fltinf x);
  56. return mkfltn result
  57. end;
  58. symbolic procedure atan x;
  59. begin scalar result;
  60. x := float x;
  61. result := gtfltn();
  62. uxatan(floatbase result,floatbase fltinf x);
  63. return mkfltn result
  64. end;
  65. symbolic procedure atan2(y,x);
  66. begin scalar result;
  67. x := float x;
  68. y := float y;
  69. result := gtfltn();
  70. uxatan2(floatbase result,floatbase fltinf y,floatbase fltinf x);
  71. return mkfltn result
  72. end;
  73. % ASEC defined in math.red.
  74. % Trig functions in degrees.
  75. symbolic procedure sind x;
  76. sin degreestoradians x;
  77. symbolic procedure cosd x;
  78. cos degreestoradians x;
  79. symbolic procedure tand x;
  80. tan degreestoradians x;
  81. symbolic procedure cotd x;
  82. cot degreestoradians x;
  83. symbolic procedure secd x;
  84. sec degreestoradians x;
  85. symbolic procedure cscd x;
  86. csc degreestoradians x;
  87. symbolic procedure asecd x;
  88. radianstodegrees asec x;
  89. symbolic procedure acscd x;
  90. radianstodegrees acsc x;
  91. symbolic procedure atan2d(y,x);
  92. radianstodegrees atan2(y,x);
  93. % Exponential, logarithm, power, square root, hypotenuse.
  94. symbolic procedure exp x;
  95. begin scalar result;
  96. x := float x;
  97. result := gtfltn();
  98. uxexp(floatbase result,floatbase fltinf x);
  99. return mkfltn result
  100. end;
  101. symbolic procedure log x;
  102. begin scalar result, ilog2x;
  103. if x <= 0.0
  104. then error(99,list("non-positive argument to LOG:",x))
  105. else if fixp(x) and (ilog2x:=ilog2(x)) > !!floatbits
  106. then return log2*(ilog2x - !!floatbits)
  107. + log(x/2^(ilog2x - !!floatbits));
  108. x := float x;
  109. result := gtfltn();
  110. uxlog(floatbase result,floatbase fltinf x);
  111. return mkfltn result
  112. end;
  113. % LOG10 in math.red.
  114. symbolic procedure sqrt x;
  115. begin scalar result;
  116. if x < 0.0
  117. then error(99,list("negative argument to SQRT:",x));
  118. x := float x;
  119. result := gtfltn();
  120. uxsqrt(floatbase result,floatbase fltinf x);
  121. return mkfltn result
  122. end;
  123. symbolic procedure hypot(x,y);
  124. begin scalar result;
  125. x := float x;
  126. y := float y;
  127. result := gtfltn();
  128. uxhypot(floatbase result,floatbase fltinf x);
  129. return mkfltn result
  130. end;
  131. % Hyperbolic functions.
  132. symbolic procedure cosh x;
  133. begin scalar result;
  134. x := float x;
  135. result := gtfltn();
  136. uxcosh(floatbase result,floatbase fltinf x);
  137. return mkfltn result
  138. end;
  139. symbolic procedure sinh x;
  140. begin scalar result;
  141. x := float x;
  142. result := gtfltn();
  143. uxsinh(floatbase result,floatbase fltinf x);
  144. return mkfltn result
  145. end;
  146. symbolic procedure tanh x;
  147. begin scalar result;
  148. x := float x;
  149. result := gtfltn();
  150. uxtanh(floatbase result,floatbase fltinf x);
  151. return mkfltn result
  152. end;
  153. (for each u in
  154. '(sin cos tan sind cosd tand cotd secd cscd asin acos atan
  155. asecd acscd atan2d atan2 sqrt exp log hypot cosh sinh tanh)
  156. do
  157. if getd intern bldmsg("%w%w",'ux,u) then flag(list u,'lose)
  158. ) where !*lower=nil;
  159. % ***** REMOVE THE FOLLOWING LINE WHEN FLOAT.C/EXTERNALS.SL UPDATED.
  160. REMFLAG('(HYPOT COSH SINH TANH),'LOSE);
  161. % ***** REMOVE THE FOLLOWING LINE WHEN WE KNOW HOW TO HANDLE COMPLEX
  162. % VALUES FOR ACOS, ASIN.
  163. REMFLAG('(ACOS ASIN),'LOSE);
  164. remflag('(cond),'eval);
  165. endmodule;
  166. end;