system/base/unknown/src/mathlib

Raw file
Back to index

PACKET mathlib DEFINES sqrt,**,exp,ln,log2,log10,sin,cos, 
                       tan,arctan,sind,cosd,tand,arctand,e,pi,
                       random,initializerandom :
 
 
REAL VAR rdg::0.4711; 
 
REAL PROC pi: 
   3.141592653589793. 
END PROC pi; 
 
REAL PROC e: 
  2.718281828459045. 
END PROC e; 
 
REAL PROC ln(REAL CONST x): 
LET ln2= 0.6931471805599453; 
log2(x)*ln2. 
END PROC ln; 
 
REAL PROC log2(REAL CONST z): 
INT VAR k::0,p::0; 
REAL VAR m::0.0,x::z,t::0.0,summe::0.0; 
IF   x>0.0 
THEN normal 
ELSE errorstop("log2 mit negativer zahl");4711.4711 
FI. 
normal: 
 IF   x>=0.5 
 THEN normalise downwards 
 ELSE normalise upwards 
  FI; 
  IF   x>=0.1 AND x< 0.7071067811865475 THEN 
       t:=(x-0.5946035575013605)/(x+0.5946035575013605); 
       summe:=reihenentwicklung (t) - 0.75 
  FI; 
  IF  x>=0.7071067811865475 AND x < 1.0 THEN 
      t:=(x - 0.8408964152537145)/(x+0.8408964152537145); 
      summe:= reihenentwicklung(t)-0.25 
  FI; 
  summe-real(p - 4*k). 
 
 normalise downwards: 
  WHILE  x>= 16.0 REP 
    x:=x/16.0;k:=k+1; 
  END REP; 
  WHILE  x>=0.5 REP 
    x:=x/2.0;p:=p-1; 
  END REP. 
 
 normalise upwards: 
  WHILE x<=0.0625 REP 
    x:=x*16.0;k:=k-1; 
  END REP; 
  WHILE x<= 0.5 REP 
    x:=x*2.0;p:=p+1; 
  END REP. 
 
END PROC log2; 
 
REAL PROC reihenentwicklung(REAL CONST x):
  REAL VAR i::39.0,s::1.0/39.0; 
  LET ln2=0.6931471805599453; 
  WHILE i>1.0 REP 
    i:=i-2.0;s:=s*x*x + 1.0/i; 
  END REP; 
  s*2.0*x/ln2. 
END PROC reihenentwicklung; 
 
REAL PROC log10(REAL CONST x): 
  LET lg2=0.301029995664; 
  log2(x)*lg2. 
END PROC log10; 
 
REAL PROC sqrt(REAL CONST z): 
  REAL VAR y0,y1,x::z; 
  INT VAR p::0; 
  BOOL VAR q::FALSE; 
  IF   x<0.0 
  THEN errorstop("sqrt von negativer zahl");0.0
  ELSE correct 
  FI. 
 
 correct: 
  IF   x=0.0 
  THEN 0.0 
  ELSE nontrivial 
  FI. 
 
 nontrivial: 
  IF   x<0.01 
  THEN small 
  ELSE notsmall 
  FI. 
 
 
 notsmall: 
  IF   x>1.0 
  THEN big 
  ELSE normal 
  FI. 
 
 small: 
  WHILE x<0.01 REP 
    p:=p-1;x:=x*100.0; 
  END REP; 
  normal. 
 
 big: 
  WHILE x>=1.0 REP
    p:=p+1;x:=x/100.0; 
  END REP; 
  normal. 
 
 normal: 
  IF   x<0.1 
  THEN x:=x*10.0;q:=TRUE 
  FI; 
  y0:=10.0**p*(1.681595-1.288973/(0.8408065+x)); 
  IF   q 
  THEN y0:=y0/3.162278 
  FI; 
  y1:=(y0+z/y0)/2.0; 
  y0:=(y1+z/y1)/2.0; 
  y1:=(y0+z/y0)/2.0; 
  (y1-z/y1)/2.0+z/y1. 
 
END PROC sqrt; 
 
REAL PROC exp(REAL CONST z): 
  REAL VAR c,d,x::z, a, b ; 
  IF   x<-180.2187 
  THEN 0.0 
  ELIF x<0.0 
  THEN 1.0/exp(-x) 
  ELIF x=0.0 
  THEN 1.0 
  ELSE x:=x/0.6931471805599453;approx 
  FI. 
 
 approx: 
  a:=floor(x/4.0)+1.0; 
  b:=floor(4.0*a-x); 
  c:=(4.0*a-b-x)*16.0; 
  d:=(c -floor(c))/16.0; 
  d:=d*0.6931471805599453; 
  ( (16.0 POWER a) / (2.0 POWER b) / (1.044273782427419 POWER c ))* 
  ((((((0.135910788320380e-2*d-0.8331563191293753e-2)*d 
  +0.4166661437490328e-1)*d-0.1666666658727157)*d+0.4999999999942539)*d 
  - 0.9999999999999844)*d+1.0). 
 
ENDPROC exp ; 
 
REAL OP POWER (REAL CONST basis, exponent) : 
 
  IF floor (exponent) = 0.0 
    THEN 1.0 
    ELSE power 
  FI . 
 
power : 
  REAL VAR counter := floor (abs (exponent)) - 1.0 , 
           result  := basis ; 
  WHILE counter > 0.0 REP 
    result := result * basis ; 
    counter := counter - 1.0 
  PER ; 
  IF exponent > 0.0 
    THEN result 
    ELSE 1.0 / result 
  FI . 
 
ENDOP POWER ; 
 
REAL PROC tan (REAL CONST x): 
  REAL VAR p; 
  p:=1.273239544735168*ABSx; 
  tg(p)*sign(x). 
END PROC tan; 
 
REAL PROC tand(REAL CONST x): 
  REAL VAR p; 
  p:=0.02222222222222222*ABSx; 
  tg(p)*sign(x). 
END PROC tand; 
 
REAL PROC tg(REAL CONST x): 
  REAL VAR r,s,u,q; 
  q:=floor(x);r:=x-q; 
  IF q = floor(q/2.0) * 2.0 
  THEN s:=r 
  ELSE s:=(1.0-r) 
  FI; 
  q:= q - floor(q/4.0) * 4.0 ; 
  u:=s*s; 
  s:=s*0.785398163397448; 
  s:=s/(((((((((-0.4018243865271481e-10*u-0.4404768172667185e-9)*u- 
  0.748183650813680e-8)*u-0.119216115119129e-6)*u-0.1909255769212821e-5)*u- 
0.3064200638849133e-4)*u-0.4967495424202482e-3)*u-0.8455650263333471e-2)*u- 
  0.2056167583560294)*u+1.0); 
  IF   q=0.0 
  THEN s 
  ELIF q=3.0 
  THEN -s 
  ELIF q=1.0 
  THEN 1.0/s 
  ELSE -1.0/s 
  FI . 
 
END PROC tg;
 
REAL PROC sin(REAL CONST x): 
  REAL VAR y,r; 
  INT VAR q; 
  y:=ABS x*1.273239544735168; 
  q:=int(y); 
  r:=y-real(q); 
  IF   x<0.0 
  THEN q:=q+4 
  FI; 
  sincos(q,r). 
END PROC sin; 
 
REAL PROC sind(REAL CONST x): 
  REAL VAR y,r; 
  INT VAR q; 
  y:=ABSx/45.0; 
  q:=int(y); 
  r:=y-real(q); 
  IF   x<0.0 
  THEN q:=q+4 
  FI; 
  sincos(q,r). 
END PROC sind; 
 
 
REAL PROC cos(REAL CONST x): 
  REAL VAR y,r; 
  INT VAR q; 
  y:=ABS x*1.273239544735168; 
  q:=int(y); 
  r:=y-real(q); 
  q:=q+2; 
  sincos(q,r). 
END PROC cos; 
 
REAL PROC cosd(REAL CONST x): 
  REAL VAR y,r; 
  INT VAR q; 
  y:=ABS x/45.0; 
  q:=int(y); 
  r:=y-real(q); 
  q:=q+2; 
  sincos(q,r). 
END PROC cosd; 
 
 
REAL PROC sincos(INT VAR q,REAL VAR r): 
  SELECT q MOD 8 + 1 OF 
  CASE 1 : sin approx(r) 
  CASE 2 : cos approx (1.0-r) 
  CASE 3 : cos approx(r) 
  CASE 4 : sin approx(1.0-r) 
  CASE 5 : - sin approx(r) 
  CASE 6 : - cos approx(1.0-r) 
  CASE 7 : - cos approx(r) 
  CASE 8 : - sin approx(1.0-r) 
  OTHERWISE 0.0 
  END SELECT 
END PROC sincos; 
 
REAL PROC sin approx(REAL CONST x): 
  REAL VAR z::x*x; 
  x*((((((0.6877101540593035e-11*z-0.1757149296873372e-8)*z+0.313361621667256
8
e-6)*z-0.3657620415845891e-4)*z+0.2490394570188737e-2)*z-0.807455121882e-1 
)*z+0.7853981633974483). 
END PROC sin approx; 
 
REAL PROC cos approx(REAL CONST x): 
  REAL VAR z::x*x; 
  (((((( -0.3857761864560276e-12*z+0.115004970178141e-9)*z-0.246113638267419e
-7)*z+0.3590860445885748e-5)*z-0.3259918869266875e-3)*z+0.1585434424381541e-1
)*z-0.3084251375340425)*z+1.0. 
END PROC cos approx; 
 
REAL PROC arctan(REAL CONST x): 
REAL VAR z::x*x; 
IF   x<0.0 THEN -arctan(-x) 
ELIF x>1.0 THEN 3.141592653589792/2.0-arctan(1.0/x) 
ELIF x*1.0e16>2.67949192431e15   THEN pi/6.0+arctan(1.732050807568877-4.0 
/(x+1.732050807568877)) 
ELSE  x/(((((((0.0107090276046822*z-0.01647757182108040)*z 
      +0.02177846332482151)*z-0.03019339673273880)*z+0.04656083561183398)*z 
      -0.0888888888888888)*z+0.3333333333333333)*z+1.0)FI. 
END PROC arctan; 
 
REAL PROC arctand(REAL CONST x): 
  arctan(x)/3.1415926589793*180.0. 
END PROC arctand; 
 
 
BOOL PROC even(INT CONST number): 
 (number DIV 2)*2=number. 
END PROC even; 
 
REAL OP **(REAL CONST base,exponent): 
  IF   base<0.0 
  THEN errorstop("hoch mit negativer basis") 
  FI; 
  IF   base=0.0 
  THEN test exponent 
  ELSE
      exp(exponent*ln(base)) 
  FI. 
 
 test exponent: 
  IF   exponent=0.0 
  THEN errorstop("0**0 geht nicht");4711.4711 
  ELSE 0.0 
  FI. 
 
END OP **; 
 
 
REAL PROC sign(REAL CONST number): 
  IF   number >0.0  THEN 1.0 
  ELIF number <0.0  THEN -1.0 
  ELSE 0.0 
  FI. 
END PROC sign ;
 
REAL OP **(REAL CONST a,INT CONST b): 
REAL VAR p::1.0,r::a;INT VAR n::ABS b; 
WHILE n>0 REP 
  IF   n MOD 2=0 
  THEN n:=n DIV 2;r:=r*r 
  ELSE n DECR 1;p:=p*r 
  FI; 
END REP; 
IF   b>0 
THEN p 
ELSE 1.0/p 
FI. 
END OP **; 
 
 
 
REAL PROC random: 
rdg:=rdg+pi;rdg:=rdg*rdg;rdg:=rdg*rdg;rdg:=rdg*rdg;rdg:=frac(rdg);rdg. 
END PROC random; 
 
 
PROC initializerandom(REAL CONST z): 
 rdg:=z; 
END PROC initializerandom; 
 
END PACKET mathlib;