math.inc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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. asm
  101. subl $16,%esp
  102. fnstcw -4(%ebp)
  103. fwait
  104. movw -4(%ebp),%cx
  105. orw $0x0c3f,%cx
  106. movw %cx,-8(%ebp)
  107. fldcw -8(%ebp)
  108. fwait
  109. fldt d
  110. fistpq -12(%ebp)
  111. movl -12(%ebp),%eax
  112. movl -8(%ebp),%edx
  113. fldcw -4(%ebp)
  114. end ['EAX','ECX','EDX'];
  115. {$define FPC_SYSTEM_HAS_ROUND}
  116. function round(d : extended) : longint;assembler;[internconst:in_const_round];
  117. asm
  118. subl $8,%esp
  119. fnstcw -4(%ebp)
  120. fwait
  121. movw $0x1372,-8(%ebp)
  122. fldcw -8(%ebp)
  123. fwait
  124. fldt d
  125. fistpl -8(%ebp)
  126. movl -8(%ebp),%eax
  127. fldcw -4(%ebp)
  128. end ['EAX','ECX'];
  129. {$define FPC_SYSTEM_HAS_POWER}
  130. function power(bas,expo : extended) : extended;
  131. begin
  132. if bas=0 then
  133. begin
  134. if expo<>0 then
  135. power:=0.0
  136. else
  137. HandleError(207);
  138. end
  139. else if expo=0 then
  140. power:=1
  141. else
  142. { bas < 0 is not allowed }
  143. if bas<0 then
  144. handleerror(207)
  145. else
  146. power:=exp(ln(bas)*expo);
  147. end;
  148. {****************************************************************************
  149. Longint data type routines
  150. ****************************************************************************}
  151. function power(bas,expo : longint) : longint;
  152. begin
  153. if bas=0 then
  154. begin
  155. if expo<>0 then
  156. power:=0
  157. else
  158. HandleError(207);
  159. end
  160. else if expo=0 then
  161. power:=1
  162. else
  163. begin
  164. if bas<0 then
  165. begin
  166. if odd(expo) then
  167. power:=-round(exp(ln(-bas)*expo))
  168. else
  169. power:=round(exp(ln(-bas)*expo));
  170. end
  171. else
  172. power:=round(exp(ln(bas)*expo));
  173. end;
  174. end;
  175. {****************************************************************************
  176. Helper routines to support old TP styled reals
  177. ****************************************************************************}
  178. function real2double(r : real48) : double;
  179. var
  180. res : array[0..7] of byte;
  181. exponent : word;
  182. begin
  183. { copy mantissa }
  184. res[0]:=0;
  185. res[1]:=r[1] shl 5;
  186. res[2]:=(r[1] shr 3) or (r[2] shl 5);
  187. res[3]:=(r[2] shr 3) or (r[3] shl 5);
  188. res[4]:=(r[3] shr 3) or (r[4] shl 5);
  189. res[5]:=(r[4] shr 3) or (r[5] and $7f) shl 5;
  190. res[6]:=(r[5] and $7f) shr 3;
  191. { copy exponent }
  192. { correct exponent: }
  193. exponent:=(word(r[0])+(1023-129));
  194. res[6]:=res[6] or ((exponent and $f) shl 4);
  195. res[7]:=exponent shr 4;
  196. { set sign }
  197. res[7]:=res[7] or (r[5] and $80);
  198. real2double:=double(res);
  199. end;
  200. {
  201. $Log$
  202. Revision 1.6 2001-07-30 21:38:54 peter
  203. * m68k updates merged
  204. Revision 1.1.2.3 2001/07/29 23:56:28 carl
  205. - removed internamth define (always internal)
  206. Revision 1.1.2.2 2001/04/16 10:56:13 peter
  207. * fixes for stricter compiler
  208. Revision 1.1.2.1 2001/04/03 20:33:01 marco
  209. * Quickfixed trunc to int64 for Sebastian.
  210. Revision 1.1 2000/07/13 06:30:42 michael
  211. + Initial import
  212. }