home *** CD-ROM | disk | FTP | other *** search
- { unit math/math87; last modified: 30OCT90 }
-
- { elementary analytical and transcendental math routines }
- { Copyright 1990, by J. W. Rider }
-
- unit {$ifopt N-} math {$else} math87 {$endif} ;
-
- interface
-
- {$IFOPT N+} const maxfloatray = 6551;
- type float=double; xfloat=extended;
- {$else} const maxfloatray = 10919;
- type float=real; xfloat=real;
- {$endif}
-
- type floatray = array [0..maxfloatray] of float;
-
- const FLOATEPS = {$ifopt N-} 1.5e-6 {$else} 3.4e-9 {$endif} ;
-
- const {strictly overkill on precision}
-
- CBRT2 = 1.2599210498948731647672;{ cube root of 2 }
- CBRT3 = 1.4422495703074083823216;{ cube root of 3 }
- D2R = 0.017453292519943295769237;{ # radians in a degree }
- E = 2.7182818284590452353603;{ base of natural logs }
- EULERC = 0.5772156649015328606065;{ Euler's constant }
- LN2 = 0.6931471805599453094172;{ natural logarithm of 2 }
- LN3 = 1.0986122886681096913952;{ natural logarithm of 3 }
- LN10 = 2.3025850929940456840280;{ natural logarithm of 10 }
- LNPI = 1.1447298858494001741434;{ natural logarithm of PI }
- LOG2E = 1.4426950408889634073599;{ 1/ln(2) }
- LOG10E = 0.4342944819032518276511;{ 1/ln(10) }
- M2R = 0.000290888208665721596154;{ # rads in a minute }
- PI = 3.1415926535897932384626;{ plain ol' round pi }
- PI_2 = 1.5707963267948966192313;{ pi/2 }
- PI_4 = 0.7853981633974483096156;{ pi/4 }
- R1_E = 0.3678794411714423215955;{ 1/e }
- R1_PI = 0.3183098861837906715378;{ 1/pi }
- R1_SQRTPI = 0.5641895835477562869481;{ 1/sqrt(pi) }
- R2_PI = 0.6366197723675813430755;{ 2/pi }
- R2_SQRTPI = 1.12837916709551257390; { 2/sqrt(pi) }
- R2D = 57.295779513082320876798;{ # degrees in a radian }
- S2R = 0.000004848136811095359936;{ # rads in a second }
- SQRPI = 9.8696044010893586188345;{ sqr(pi) (not round!) }
- SQRT_2 = 0.707106781186547524401; { sqrt(1/2) }
- SQRT2 = 1.4142135623730950488017;{ sqrt(2) }
- SQRT2PI = 2.5066282746310005024158;{ sqrt(2*pi) }
- SQRT3 = 1.7320508075688772935; { sqrt(3) }
- SQRT5 = 2.2360679774997896964; { sqrt(5) }
- SQRTPI = 1.7724538509055160272982;{ sqrt(pi) = gamma(1/2) }
- TWOPI = 6.2831853071795864769253;{ 2*pi }
-
- function acos (x: xfloat): xfloat ;
- function acosd (x: xfloat): xfloat ;
- function acosh (x: xfloat): xfloat ;
- function asin (x: xfloat): xfloat ;
- function asind (x: xfloat): xfloat ;
- function asinh (x: xfloat): xfloat ;
- function atan (x: xfloat): xfloat ;
- function atand (x: xfloat): xfloat ;
- function atanh (x: xfloat): xfloat ;
- function ceil (x: xfloat): xfloat ;
- function cosd (x: xfloat): xfloat ;
- function cosh (x: xfloat): xfloat ;
- function deg2rad(x: xfloat): xfloat ;
- function exp (x: xfloat): xfloat ;
- function exp2 (x: xfloat): xfloat ;
- function exp10 (x: xfloat): xfloat ;
- function floor (x: xfloat): xfloat ;
- function ln (x: xfloat): xfloat ;
- function log (x: xfloat): xfloat ;
- function log2 (x: xfloat): xfloat ;
- function log10 (x: xfloat): xfloat ;
- function pow10 (x: xfloat): xfloat ;
- function rad2deg(x: xfloat): xfloat ;
- function sgn (x: xfloat): xfloat ;
- function sind (x: xfloat): xfloat ;
- function sinh (x: xfloat): xfloat ;
- function sqrt (x: xfloat): xfloat ;
- function tan (x: xfloat): xfloat ;
- function tand (x: xfloat): xfloat ;
- function tanh (x: xfloat): xfloat ;
-
- function atan2 (x,y: xfloat): xfloat ;
- function atan2d (x,y: xfloat): xfloat ;
- function fdiv (x,y: xfloat): xfloat ;
- function fmod (x,y: xfloat): xfloat ;
- function frem (x,y: xfloat): xfloat ;
- function hypot (x,y: xfloat): xfloat ;
- function ipow (x,y: xfloat): xfloat ;
- function iroot (x,y: xfloat): xfloat ;
- function max (x,y: xfloat): xfloat ;
- function min (x,y: xfloat): xfloat ;
- function pow (x,y: xfloat): xfloat ;
- function root (x,y: xfloat): xfloat ;
-
- function iif (p: boolean; t,f: xfloat): xfloat ;
- function powi (x: xfloat; n: integer): xfloat ;
- function round2 (x: xfloat; n: shortint): xfloat ;
-
- function frexp (x: xfloat; var epart: longint): xfloat ;
- function ldexp (x: xfloat; epart: longint): xfloat ;
-
- function modf (x: xfloat; var ipart: float): xfloat ;
- function remf (x: xfloat; var ipart: float): xfloat ;
-
- function dms2deg (d,m,s: xfloat): xfloat;
- function dms2rad (d,m,s: xfloat): xfloat;
-
- procedure deg2dms (deg: xfloat; var d,m,s: float);
- procedure rad2dms ( r: xfloat; var d,m,s: float);
-
- function poly (x: xfloat; degree: integer; var coeffs ): xfloat;
-
-
- implementation
-
- function acos; var y:xfloat; begin
- y:=sqrt(1-sqr(x));
- if abs(x)<=y then acos:=PI_2-arctan(x/y)
- else acos:=arctan(y/x)+iif(x<0,PI,0) end;
-
- function acosd; begin acosd:=rad2deg(acos(x)) end;
- function acosh; begin acosh:=ln(sqrt(sqr(x)-1)+x) end;
-
- function asin; var y:xfloat; begin
- y:=sqrt(1-sqr(x));
- if abs(x)<=y then asin:=arctan(x/y)
- else asin:=sgn(x)*PI_2-arctan(y/x) end;
-
- function asind; begin asind:=rad2deg(asin(x)) end;
- function asinh; begin asinh:=system.ln(system.sqrt(sqr(x)+1)+x) end;
-
- function atan; begin atan:=arctan(x) end;
- function atand; begin atand:=rad2deg(arctan(x)) end;
-
- function atan2; begin
- if abs(x)>abs(y) then atan2:=arctan(y/x)+iif(x>0,0,sgn(y)*PI)
- else if abs(x)<abs(y) then atan2:=(PI_2-arctan(x/y))*sgn(y)
- else atan2:=sgn(y)*iif(x<0,3,1)*PI_4 end;
-
- function atan2d; begin atan2d:=rad2deg(atan2(x,y)) end;
- function atanh; begin atanh:=ln((1+x)/(1-x))*0.5 end;
-
- function ceil; var intx:xfloat; begin
- intx:=int(x); if intx>=x then ceil:=intx else ceil:=intx+1 end;
-
- function cosd; begin cosd:=cos(deg2rad(x)) end;
-
- function cosh; var expx:xfloat; begin
- expx:=system.exp(x); cosh:=(sqr(expx)+1)/(expx*2) end;
-
- procedure deg2dms; begin s:=remf(remf(deg,d)*60,m)*60 end;
- function deg2rad; begin deg2rad:=x*D2R end;
-
- function dms2deg; const R1_60 = 1.0/60.0; begin
- dms2deg:=(s*R1_60+m)*R1_60+d end;
-
- function dms2rad; begin dms2rad:=d*D2R+m*M2R+s*S2R end;
-
- function exp;
- const MAXEXPD = {$IFOPT N-} 88.0296919311
- {$ELSE } 11356.52340629414394 {$ENDIF};
- begin if x < -MAXEXPD then exp:=0 else exp:=system.exp(x) end;
-
- function exp2; begin exp2:=exp(x*LN2) end;
- function exp10; begin exp10:=exp(x*LN10) end;
- function fdiv; begin fdiv:=int(x/y) end;
-
- function floor; var intx:xfloat; begin
- intx:=int(x); if intx<=x then floor:=intx else floor:=intx-1 end;
-
- function fmod; begin fmod:=x-floor(x/y)*y end;
- function frem; begin frem:=x-int(x/y)*y end;
-
- { WARNING: "frexp" accesses the representation of floating point
- numbers at the bit level. This makes the routine very
- non-portable. }
- function frexp;
- type byteray = array [0..pred(sizeof(xfloat))] of byte;
- wordray = array [0..pred(sizeof(xfloat) div 2)] of word;
- begin if x=0 then begin frexp:=0; epart:=0 end
- else begin
- {$IFOPT N-}
- epart:=integer(byteray(x)[0])-128;
- byteray(x)[0]:=128;
- {$ELSE}
- epart:=longint(wordray(x)[4] and $7fff)-16382;
- wordray(x)[4]:=(wordray(x)[4] and $8000) or 16382;
- {$ENDIF}
- frexp:=x end end; { frexp }
-
- function hypot; begin hypot:=system.sqrt(sqr(x)+sqr(y)) end;
- function iif; begin if p then iif:=t else iif:=f end;
-
- function ipow; begin
- if (x>=0) or (y=0) then ipow:= 0
- else ipow:= sin(frac(y*0.5)*TWOPI)*pow(abs(x),y) end;
-
- function iroot; begin iroot:=ipow(x,1/y) end;
-
- { WARNING: "ldexp" accesses the representation of floating point
- numbers at the bit level. This makes the routine very
- non-portable. }
- function ldexp;
- type byteray = array [0..pred(sizeof(xfloat))] of byte;
- wordray = array [0..pred(sizeof(xfloat) div 2)] of word;
- var y:word;
- begin if x=0 then ldexp:=0
- else begin
- {$IFOPT N-}
- inc(byteray(x)[0],epart);
- {$ELSE}
- y:=wordray(x)[4];
- wordray(x)[4]:=(y and $8000) or word((y and $7fff)+epart);
- {$ENDIF}
- ldexp:=x end end; { ldexp }
-
- function ln; begin
- if abs(x-1)<FLOATEPS then ln:=x-1
- else ln:=system.ln(abs(x)) end;
-
- function log; begin log:=ln(x) end;
- function log2; begin log2:=ln(x)*LOG2E end;
- function log10; begin log10:=ln(x)*LOG10E end;
- function max; begin max:=iif(x>=y,x,y) end;
- function min; begin min:=iif(x<=y,x,y) end;
- function modf; begin ipart:=floor(x); modf:=x-ipart end;
-
- function poly; var y:xfloat; begin
- { coeffs is assumed to be an array [0..degree] of "float" }
- y:=0;
- while degree>=0 do begin
- y:= y*x + floatray(coeffs)[degree]; dec(degree) end;
- poly:=y end;
-
- function pow; begin
- if x>0 then pow:= exp(ln(x)*y)
- else if x=0 then pow:= 0 { pow(0,0)=0 instead of "indeterminate" }
- else if y=0 then pow:= 1
- else pow:= cos(frac(y*0.5)*TWOPI)*pow(abs(x),y) end;
-
- function pow10; begin pow10:=exp10(x) end;
-
- function powi; var z:xfloat; begin
- if n>0 then begin
- z:=sqr(powi(x,n shr 1));
- if odd(n) then powi:=z*x
- else powi:=z end
- else if n=0 then powi:=iif(x=0,0,1)
- else { if n<0 then } powi:=1/powi(x,-n) end;
-
- function rad2deg; begin rad2deg:=x*R2D end;
- procedure rad2dms; begin deg2dms(rad2deg(r),d,m,s) end;
- function remf; begin ipart:=int(x); remf:=frac(x) end;
- function root; begin root:=pow(x,1/y) end;
-
- function round2; var d:xfloat; begin
- d:=powi(10,abs(n));
- if n<0 then round2:=round(x/d)*d
- else round2:=round(frac(x)*d)/d+int(x) end;
-
- function sgn; begin if x=0 then sgn:=0 else sgn:=iif(x>0,1,-1) end;
- function sind; begin sind:=sin(deg2rad(x)) end;
-
- function sinh; var expx:xfloat; begin
- expx:=system.exp(x); sinh:=(sqr(expx)-1)/(expx*2) end;
-
- function sqrt; begin sqrt:=system.sqrt(abs(x))*sgn(x) end;
- function tan; begin tan:=sin(x)/cos(x) end;
- function tand; begin tand:=tan(deg2rad(x)) end;
-
- function tanh;
- const MAXTANHD = {$IFOPT N-} 44.0148459655
- {$ELSE } 5678.26170314707197 {$ENDIF};
- var exp2x:xfloat;
- begin if abs(x)>=MAXTANHD then tanh:=sgn(x)
- else begin exp2x:=exp(2*x); tanh:=(exp2x-1)/(exp2x+1) end end;
-
- end. { Unit MATH/MATH87 }