math.inc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2001 by the Free Pascal development team
  5. Implementation of mathematical routines (for extended type)
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {****************************************************************************
  13. EXTENDED data type routines
  14. ****************************************************************************}
  15. {$define FPC_SYSTEM_HAS_PI}
  16. function pi : extended;[internproc:in_pi];
  17. {$define FPC_SYSTEM_HAS_ABS}
  18. function abs(d : extended) : extended;[internproc:in_abs_extended];
  19. {$define FPC_SYSTEM_HAS_SQR}
  20. function sqr(d : extended) : extended;[internproc:in_sqr_extended];
  21. {$define FPC_SYSTEM_HAS_SQRT}
  22. function sqrt(d : extended) : extended;[internproc:in_sqrt_extended];
  23. {$define FPC_SYSTEM_HAS_ARCTAN}
  24. function arctan(d : extended) : extended;[internproc:in_arctan_extended];
  25. {$define FPC_SYSTEM_HAS_LN}
  26. function ln(d : extended) : extended;[internproc:in_ln_extended];
  27. {$define FPC_SYSTEM_HAS_SIN}
  28. function sin(d : extended) : extended;[internproc:in_sin_extended];
  29. {$define FPC_SYSTEM_HAS_COS}
  30. function cos(d : extended) : extended;[internproc:in_cos_extended];
  31. {$define FPC_SYSTEM_HAS_EXP}
  32. function exp(d : extended) : extended;assembler;[internconst:in_const_exp];
  33. asm
  34. // comes from DJ GPP
  35. fldt d
  36. fldl2e
  37. fmulp %st,%st(1)
  38. fstcw .LCW1
  39. fstcw .LCW2
  40. andw $0xf3ff,.LCW2
  41. orw $0x0400,.LCW2
  42. fldcw .LCW2
  43. fld %st(0)
  44. frndint
  45. fldcw .LCW1
  46. fxch %st(1)
  47. fsub %st(1),%st
  48. f2xm1
  49. fld1
  50. faddp %st,%st(1)
  51. fscale
  52. fstp %st(1)
  53. jmp .LCW3
  54. // store some help data in the data segment
  55. .data
  56. .LCW1:
  57. .word 0
  58. .LCW2:
  59. .word 0
  60. .text
  61. .LCW3:
  62. end;
  63. {$define FPC_SYSTEM_HAS_FRAC}
  64. function frac(d : extended) : extended;assembler;[internconst:in_const_frac];
  65. asm
  66. subl $16,%esp
  67. fnstcw -4(%ebp)
  68. fwait
  69. movw -4(%ebp),%cx
  70. orw $0x0c3f,%cx
  71. movw %cx,-8(%ebp)
  72. fldcw -8(%ebp)
  73. fwait
  74. fldt d
  75. frndint
  76. fldt d
  77. fsub %st(1),%st
  78. fstp %st(1)
  79. fclex
  80. fldcw -4(%ebp)
  81. end ['ECX'];
  82. {$define FPC_SYSTEM_HAS_INT}
  83. function int(d : extended) : extended;assembler;[internconst:in_const_int];
  84. asm
  85. subl $16,%esp
  86. fnstcw -4(%ebp)
  87. fwait
  88. movw -4(%ebp),%cx
  89. orw $0x0c3f,%cx
  90. movw %cx,-8(%ebp)
  91. fldcw -8(%ebp)
  92. fwait
  93. fldt d
  94. frndint
  95. fclex
  96. fldcw -4(%ebp)
  97. end ['ECX'];
  98. {$define FPC_SYSTEM_HAS_TRUNC}
  99. function trunc(d : extended) : int64;assembler;[internconst:in_const_trunc];
  100. var
  101. oldcw,
  102. newcw : word;
  103. res : int64;
  104. asm
  105. fnstcw oldcw
  106. fwait
  107. movw oldcw,%cx
  108. orw $0x0c3f,%cx
  109. movw %cx,newcw
  110. fldcw newcw
  111. fwait
  112. fldt d
  113. fistpq res
  114. movl res,%eax
  115. movl res+4,%edx
  116. fldcw oldcw
  117. end ['EAX','ECX','EDX'];
  118. {$define FPC_SYSTEM_HAS_ROUND}
  119. function round(d : extended) : int64;assembler;[internconst:in_const_round];
  120. var
  121. oldcw,
  122. newcw : word;
  123. res : int64;
  124. asm
  125. fnstcw oldcw
  126. fwait
  127. movw $0x1372,newcw
  128. fldcw newcw
  129. fwait
  130. fldt d
  131. fistpq res
  132. movl res,%eax
  133. movl res+4,%edx
  134. fldcw oldcw
  135. end ['EAX','ECX'];
  136. {$define FPC_SYSTEM_HAS_POWER}
  137. function power(bas,expo : extended) : extended;
  138. begin
  139. if bas=0 then
  140. begin
  141. if expo<>0 then
  142. power:=0.0
  143. else
  144. HandleError(207);
  145. end
  146. else if expo=0 then
  147. power:=1
  148. else
  149. { bas < 0 is not allowed }
  150. if bas<0 then
  151. handleerror(207)
  152. else
  153. power:=exp(ln(bas)*expo);
  154. end;
  155. {****************************************************************************
  156. Longint data type routines
  157. ****************************************************************************}
  158. function power(bas,expo : longint) : longint;
  159. begin
  160. if bas=0 then
  161. begin
  162. if expo<>0 then
  163. power:=0
  164. else
  165. HandleError(207);
  166. end
  167. else if expo=0 then
  168. power:=1
  169. else
  170. begin
  171. if bas<0 then
  172. begin
  173. if odd(expo) then
  174. power:=-round(exp(ln(-bas)*expo))
  175. else
  176. power:=round(exp(ln(-bas)*expo));
  177. end
  178. else
  179. power:=round(exp(ln(bas)*expo));
  180. end;
  181. end;
  182. {
  183. $Log$
  184. Revision 1.9 2002-10-06 21:26:17 peter
  185. * round returns int64
  186. Revision 1.8 2002/09/07 16:01:19 peter
  187. * old logs removed and tabs fixed
  188. }